无循环的

无循环的

我设法编写了以下脚本:

#!/bin/bash

#files list
file1=/tmp/1wall_long.txt
file2=/tmp/1wall_test1.txt
file3=/tmp/1wall_test2.txt
file4=/tmp/1wall_test3.txt
file5=/tmp/3mt_long.txt
file6=/tmp/3mt_OpenSpace_test1.txt
file7=/tmp/3mt_OpenSpace_test2.txt
file8=/tmp/3mt_OpenSpace_test3.txt
file9=/tmp/3rooms_test1.txt
file10=/tmp/3rooms_test2.txt
file11=/tmp/3rooms_test3.txt
file12=/tmp/20mt_OpenSpace_test1.txt
file13=/tmp/20mt_OpenSpace_test2.txt
file14=/tmp/20mt_OpenSpace_test3.txt

#script for 1wall_long file
if [ ! -e "$file1" ]; then #check if the file exist
    echo "File 1wall_long.txt does not exist" #if not exist print echo output
else
    sed -i -e 's/- /-/g' $file1 #remove space on the first 10 values
    awk '{print $7}' $file1 > /tmp/1wall_long_S.txt #print the column number 7 and copy the output in a file
    rm $file1 #remove old file
fi

对变量中描述的所有文件重复该脚本(基本上我使用不同的变量重复相同的脚本 14 次)是否有更好的方法来做到这一点以及这些情况下的最佳实践是什么?

答案1

无循环的

首先使用一个函数

function sevenc
{


if [ ! -e "$1" ]; then #check if the file exist
    echo "File $1 does not exist" #if not exist print echo output
else
    sed -i -e 's/- /-/g' "$1" #remove space on the first 10 values
    awk '{print $7}' "$1" > /tmp/$(basename $1.txt)_S.txt #print the column number 7 and copy the output in a file
    rm "$1"  #remove old file
fi
}
  • 当 shell 识别一个函数时,它将传递参数(如果有的话,传递给 $1 $2 ...等等)。
  • 顺便一提

's/- /-/g' "$1" #删除前 10 个值上的空格

不,它会全部转到space-线上-,无论是 1、4、10 还是 255。

那么不需要更多的var

sevenc /tmp/1wall_long.txt
sevenc /tmp/1wall_test1.txt
sevenc /tmp/1wall_test2.txt
sevenc /tmp/1wall_test3.txt
sevenc /tmp/3mt_long.txt
sevenc /tmp/3mt_OpenSpace_test1.txt
sevenc /tmp/3mt_OpenSpace_test2.txt
sevenc /tmp/3mt_OpenSpace_test3.txt
sevenc /tmp/3rooms_test1.txt
sevenc /tmp/3rooms_test2.txt
sevenc /tmp/3rooms_test3.txt
sevenc /tmp/20mt_OpenSpace_test1.txt
sevenc /tmp/20mt_OpenSpace_test2.txt
sevenc /tmp/20mt_OpenSpace_test3.txt

(前提是您不再使用 fileXX var)。

无循环(解决方案 2)

如果你想传递更多参数,并使用 Terdon 的优化尝试

function eight
{

file=$1
destdir=${2-/tmp} # use second arg if defined, else /tmp
exten=${3-S} 

if [ ! -e "$file" ]; then #check if the file exist
    echo "File $file does not exist" #if not exist print echo output
else
    sed  -e 's/- /-/g' "$file" \
    awk '{print $7}' "$1" > /"$destdir"/$(basename $1.txt)_"$exten".txt #print the column number 7 and copy the output in a file
    rm "$file"  #remove old file
fi
}

被称为与

eight /tmp/1wall_test3.txt /my/projec/dir T ## will use /my/project/dir as dit, T as extension
eight /tmp/1wall_test1.txt /my/project ## will use /my/project as dir
eignt /tmp/1wall_test2.txt ## will use default value

这些函数可以在 .bashrc 中定义并交互使用。

带循环

while read f
do
if [ ! -e "$f" ]; then #check if the file exist
    echo "File $1 does not exist" #if not exist print echo output
else
    sed -i -e 's/- /-/g' "$f" #remove space on the first 10 values
    awk '{print $7}' "$f" > "/tmp/$(basename $f .txt)_S.txt" #print the column number 7 and copy the output in a file
    rm "$f"  #remove old file
fi
done <<EOF
/tmp/1wall_long.txt
/tmp/1wall_test1.txt
/tmp/1wall_test2.txt
/tmp/1wall_test3.txt
/tmp/3mt_long.txt
/tmp/3mt_OpenSpace_test1.txt
/tmp/3mt_OpenSpace_test2.txt
/tmp/3mt_OpenSpace_test3.txt
/tmp/3rooms_test1.txt
/tmp/3rooms_test2.txt
/tmp/3rooms_test3.txt
/tmp/20mt_OpenSpace_test1.txt
/tmp/20mt_OpenSpace_test2.txt
/tmp/20mt_OpenSpace_test3.txt
EOF

答案2

就我个人而言,我会避免对文件名进行硬编码。这很少是一个好主意,通常最好选择将目标文件作为参数传递。此外,您正在就地修改文件,然后删除原始文件。这效率不高,只需动态修改文件并打印第七列,而无需将其写入磁盘。例如:

#!/usr/bin/env bash

## Iterate over the file names given
for file in "$@"; do
    ## Get the output file's name. The ${file%.*} is
    ## the file's anme without its extension.
    outfile="${file%.*}"_S.txt
    ## If the file exists
    if [ -e "$file" ]; then
    ## remove the spaces and print the 7th column
    sed 's/- /-/g' "$file" | awk '{print $7}' > "$outfile" &&
        ## Delete the original but only if the step
        ## above was successful (that's what the && does)/
        rm "$file" 
    else
    ## If the file doesn't exist, print an error message
    echo "The file $file does not exist!"
    fi
done

然后,您可以像这样运行脚本:

foo.sh /tmp/1wall_long.txt /tmp/1wall_test1.txt /tmp/1wall_test2.txt /tmp/1wall_test3.txt /tmp/20mt_OpenSpace_test1.txt /tmp/20mt_OpenSpace_test2.txt /tmp/20mt_OpenSpace_test3.txt /tmp/3mt_long.txt /tmp/3mt_OpenSpace_test1.txt /tmp/3mt_OpenSpace_test2.txt /tmp/3mt_OpenSpace_test3.txt /tmp/3rooms_test1.txt /tmp/3rooms_test2.txt /tmp/3rooms_test3.txt 

如果您确实想要对名称进行硬编码,只需使用 @choroba 建议的数组:

#!/usr/bin/env bash

files=(/tmp/1wall_long.txt /tmp/1wall_test1.txt /tmp/1wall_test2.txt /tmp/1wall_test3.txt /tmp/20mt_OpenSpace_test1.txt /tmp/20mt_OpenSpace_test2.txt /tmp/20mt_OpenSpace_test3.txt /tmp/3mt_long.txt /tmp/3mt_OpenSpace_test1.txt /tmp/3mt_OpenSpace_test2.txt /tmp/3mt_OpenSpace_test3.txt /tmp/3rooms_test1.txt /tmp/3rooms_test2.txt /tmp/3rooms_test3.txt )


## Iterate over the file names given
for file in "${files[@]}"; do
    ## Get the output file's name. The ${file%.*} is
    ## the file's anme without its extension.
    outfile="${file%.*}"_S.txt
    ## If the file exists
    if [ -e "$file" ]; then
    ## remove the spaces and print the 7th column
    sed 's/- /-/g' "$file" | awk '{print $7}' > "$outfile" &&
        ## Delete the original but only if the step
        ## above was successful (that's what the && does)/
        rm "$file" 
    else
    ## If the file doesn't exist, print an error message
    echo "The file $file does not exist!"
    fi
done

答案3

您可以使用文件数组并使用以下命令循环它for

#!/bin/bash

files=(/tmp/1wall_long.txt
       /tmp/1wall_test1.txt
       /tmp/1wall_test2.txt
       /tmp/1wall_test3.txt
       /tmp/3mt_long.txt
       /tmp/3mt_OpenSpace_test1.txt
       /tmp/3mt_OpenSpace_test2.txt
       /tmp/3mt_OpenSpace_test3.txt
       /tmp/3rooms_test1.txt
       /tmp/3rooms_test2.txt
       /tmp/3rooms_test3.txt
       /tmp/20mt_OpenSpace_test1.txt
       /tmp/20mt_OpenSpace_test2.txt
       /tmp/20mt_OpenSpace_test3.txt )

for file in "${files[@]}" ; do
    if [ ! -e "$file" ]; then
        echo "File $file does not exist"
    else
        sed -i -e 's/- /-/g' "$file"
        # Use parameter expansion to create the new file name.
        newfile=${file%.txt}_S.txt
        awk '{print $7}' "$file" > "$newfile"
        rm "$file"
    fi
done

相关内容