Bash脚本处理包含输入字符串的数据

时间:2021-07-09 15:45:17

I am trying to create a script that will find all the files in a folder that contain, for example, the string 'J34567' and process them. Right now I can process all the files in the folder with my code, however, my script will not just process the contained string it will process all the files in the folder. In other words once I run the script even with the string name ./bashexample 'J37264' it will still process all the files even without that string name. Here is my code below:

我正在尝试创建一个脚本,它将查找包含例如字符串'J34567'的文件夹中的所有文件并处理它们。现在我可以用我的代码处理文件夹中的所有文件,但是,我的脚本不会只处理包含的字符串,它将处理文件夹中的所有文件。换句话说,一旦我使用字符串名称./bashexample'J37264'运行脚本,即使没有该字符串名称,它仍将处理所有文件。这是我的代码如下:

#!/bin/bash

directory=$(cd `dirname .` && pwd)
tag=$1

echo find: $tag on $directory

find $directory . -type f -exec grep -sl "$tag"  {} \;

for files in $directory/*$tag*
do
    for i in *.std
    do
    /projects/OPSLIB/BCMTOOLS/sumfmt_linux < $i > $i.sum
    done

    for j in *.txt
    do
    egrep "device|Device|\(F\)" $i > $i.fail
    done
    echo $files
done

3 个解决方案

#1


1  

Kevin, you could try the following:

凯文,你可以尝试以下方法:

#!/bin/bash

directory='/home'
tag=$1


for files in $directory/*$tag*
do
    if [ -f $files ]
    then
            #do your stuff
            echo $files
    fi 
done

where directory is your directory name (you could pass it as a command-line argument too) and tag is the search term you are looking for in a filename.

其中directory是您的目录名称(您也可以将其作为命令行参数传递),tag是您在文件名中查找的搜索词。

#2


0  

Following script will give you the list of files that contain (inside the file, not in file name) the given pattern.

下面的脚本将为您提供包含(在文件内,而不是文件名中)给定模式的文件列表。

#!/bin/bash

directory=`pwd`
tag=$1

for file in $(find "$directory" -type f -exec grep -l "$tag" {} \;); do
    echo $file
    # use $file for further operations
done

What is the relevance of .std, .txt, .sum and .fail files to the files containing given pattern?

.std,.txt,.sum和.fail文件与包含给定模式的文件的相关性是什么?

Its assumed there are no special characters, spaces, etc. in file names.
If that is the case following should help working around those.
How can I escape white space in a bash loop list?
Capturing output of find . -print0 into a bash array

假设文件名中没有特殊字符,空格等。如果是这样的话应该有助于解决这些问题。如何在bash循环列表中转义空格?捕获查找的输出。 -print0进入bash数组


There are multiple issues in your script.

您的脚本中存在多个问题。

Following is not required to set the operating directory to current directory.

将操作目录设置为当前目录不需要以下操作。

directory=$(cd `dirname .` && pwd)

find is executed twice for the current directory due to $directory and ..

由于$ directory和..导致当前目录执行两次

find $directory . -type f -exec grep -sl "$tag"  {} \;

Also, result/output of above find is not used in for loop.
For loop is run for files in the $directory (sub directories not considered) with their file name having the given pattern.

此外,上述find的结果/输出不用于for循环。 For循环运行$目录中的文件(未考虑子目录),文件名具有给定的模式。

for files in $directory/*$tag*

Following for loop will run for all .txt files in current directory, but will result in only one output file due to use of $i from previous loop.

以下for循环将针对当前目录中的所有.txt文件运行,但由于使用了前一循环中的$ i,因此将只生成一个输出文件。

for j in *.txt
do
    egrep "device|Device|\(F\)" $i > $i.fail
done

#3


0  

This is my temporary solution. Please check if it follows your intention.

这是我的临时解决方案。请检查它是否符合您的意图。

#!/bin/bash

directory=$(cd `dirname .` && pwd)  ## Should this be just directory=$PWD ?
tag=$1

echo "find: $tag on $directory"

find "$directory" . -type f -exec grep -sl "$tag" {} \;  ## Shouldn't you add -maxdepth 1 ? Are the files listed here the one that should be processed in the loop below instead?

for file in "$directory"/*"$tag"*; do
    if [[ $file == *.std ]]; then
        /projects/OPSLIB/BCMTOOLS/sumfmt_linux < "$file" > "${file}.sum"
    fi

    if [[ $file == *.txt ]]; then
        egrep "device|Device|\(F\)" "$file" > "${file}.fail"
    fi

    echo "$file"
done

Update 1

更新1

#!/bin/bash

directory=$PWD  ## Change this to another directory if needed.
tag=$1

echo "find: $tag on $directory"

while IFS= read -rd $'\0' file; do
    echo "$file"
    case "$file" in
    *.std)
        /projects/OPSLIB/BCMTOOLS/sumfmt_linux < "$file" > "${file}.sum"
        ;;
    *.txt)
        egrep "device|Device|\(F\)" "$file" > "${file}.fail"
        ;;
    *)
        echo "Unexpected match: $file"
        ;;
    esac
done < <(exec find "$directory" -maxdepth 1 -type f -name "*${tag}*" \( -name '*.std' -or -name '*.txt' \) -print0)  ## Change or remove the maxdepth option as wanted.

Update 2

更新2

#!/bin/bash

directory=$PWD
tag=$1

echo "find: $tag on $directory"

while IFS= read -rd $'\0' file; do
    echo "$file"
    /projects/OPSLIB/BCMTOOLS/sumfmt_linux < "$file" > "${file}.sum"
done < <(exec find "$directory" . -maxdepth 1 -type f -name "*${tag}*" -name '*.std' -print0)

while IFS= read -rd $'\0' file; do
    echo "$file"
    egrep "device|Device|\(F\)" "$file" > "${file}.fail"
done < <(exec find "$directory" -maxdepth 1 -type f -name "*${tag}*" -name '*.txt' -print0)

#1


1  

Kevin, you could try the following:

凯文,你可以尝试以下方法:

#!/bin/bash

directory='/home'
tag=$1


for files in $directory/*$tag*
do
    if [ -f $files ]
    then
            #do your stuff
            echo $files
    fi 
done

where directory is your directory name (you could pass it as a command-line argument too) and tag is the search term you are looking for in a filename.

其中directory是您的目录名称(您也可以将其作为命令行参数传递),tag是您在文件名中查找的搜索词。

#2


0  

Following script will give you the list of files that contain (inside the file, not in file name) the given pattern.

下面的脚本将为您提供包含(在文件内,而不是文件名中)给定模式的文件列表。

#!/bin/bash

directory=`pwd`
tag=$1

for file in $(find "$directory" -type f -exec grep -l "$tag" {} \;); do
    echo $file
    # use $file for further operations
done

What is the relevance of .std, .txt, .sum and .fail files to the files containing given pattern?

.std,.txt,.sum和.fail文件与包含给定模式的文件的相关性是什么?

Its assumed there are no special characters, spaces, etc. in file names.
If that is the case following should help working around those.
How can I escape white space in a bash loop list?
Capturing output of find . -print0 into a bash array

假设文件名中没有特殊字符,空格等。如果是这样的话应该有助于解决这些问题。如何在bash循环列表中转义空格?捕获查找的输出。 -print0进入bash数组


There are multiple issues in your script.

您的脚本中存在多个问题。

Following is not required to set the operating directory to current directory.

将操作目录设置为当前目录不需要以下操作。

directory=$(cd `dirname .` && pwd)

find is executed twice for the current directory due to $directory and ..

由于$ directory和..导致当前目录执行两次

find $directory . -type f -exec grep -sl "$tag"  {} \;

Also, result/output of above find is not used in for loop.
For loop is run for files in the $directory (sub directories not considered) with their file name having the given pattern.

此外,上述find的结果/输出不用于for循环。 For循环运行$目录中的文件(未考虑子目录),文件名具有给定的模式。

for files in $directory/*$tag*

Following for loop will run for all .txt files in current directory, but will result in only one output file due to use of $i from previous loop.

以下for循环将针对当前目录中的所有.txt文件运行,但由于使用了前一循环中的$ i,因此将只生成一个输出文件。

for j in *.txt
do
    egrep "device|Device|\(F\)" $i > $i.fail
done

#3


0  

This is my temporary solution. Please check if it follows your intention.

这是我的临时解决方案。请检查它是否符合您的意图。

#!/bin/bash

directory=$(cd `dirname .` && pwd)  ## Should this be just directory=$PWD ?
tag=$1

echo "find: $tag on $directory"

find "$directory" . -type f -exec grep -sl "$tag" {} \;  ## Shouldn't you add -maxdepth 1 ? Are the files listed here the one that should be processed in the loop below instead?

for file in "$directory"/*"$tag"*; do
    if [[ $file == *.std ]]; then
        /projects/OPSLIB/BCMTOOLS/sumfmt_linux < "$file" > "${file}.sum"
    fi

    if [[ $file == *.txt ]]; then
        egrep "device|Device|\(F\)" "$file" > "${file}.fail"
    fi

    echo "$file"
done

Update 1

更新1

#!/bin/bash

directory=$PWD  ## Change this to another directory if needed.
tag=$1

echo "find: $tag on $directory"

while IFS= read -rd $'\0' file; do
    echo "$file"
    case "$file" in
    *.std)
        /projects/OPSLIB/BCMTOOLS/sumfmt_linux < "$file" > "${file}.sum"
        ;;
    *.txt)
        egrep "device|Device|\(F\)" "$file" > "${file}.fail"
        ;;
    *)
        echo "Unexpected match: $file"
        ;;
    esac
done < <(exec find "$directory" -maxdepth 1 -type f -name "*${tag}*" \( -name '*.std' -or -name '*.txt' \) -print0)  ## Change or remove the maxdepth option as wanted.

Update 2

更新2

#!/bin/bash

directory=$PWD
tag=$1

echo "find: $tag on $directory"

while IFS= read -rd $'\0' file; do
    echo "$file"
    /projects/OPSLIB/BCMTOOLS/sumfmt_linux < "$file" > "${file}.sum"
done < <(exec find "$directory" . -maxdepth 1 -type f -name "*${tag}*" -name '*.std' -print0)

while IFS= read -rd $'\0' file; do
    echo "$file"
    egrep "device|Device|\(F\)" "$file" > "${file}.fail"
done < <(exec find "$directory" -maxdepth 1 -type f -name "*${tag}*" -name '*.txt' -print0)