用于循环文件的Bash脚本

时间:2022-10-19 13:56:57

I have several files in a folder, e.g. in \home\ directory. Now I want a bash script which loops through all the files and executes a command for each file (the command uses the file name).

我在文件夹中有几个文件,例如在\ home \目录中。现在我想要一个bash脚本循环遍历所有文件并为每个文件执行一个命令(该命令使用文件名)。

How can I do this?

我怎样才能做到这一点?

4 个解决方案

#1


for file in *;
do
    echo $file
done

#2


Something like this might help you get started:

这样的事情可能会帮助你开始:

for file in /home/directory/*; do
filename=${file##*/}
echo "$filename"
##execute command here with $filename
done

If there are folders too in that directory then you will need to check for files:

如果该目录中也有文件夹,则需要检查文件:

add this line immediately after for..do:

在for..do之后立即添加此行:

[[ ! -f $file ]] && continue

If you want to ignore symbolic links, then:

如果要忽略符号链接,则:

[[ ! -f $file || -L $file ]] && continue

Additional (according to comment):

附加(根据评论):

You can check if a string (mask) is in the file name or not with:

您可以使用以下命令检查文件名中是否包含字符串(掩码):

if [[ $filename == *mask* ]];then
echo it's there
else
echo It's not there
fi

You can modify the filename like this:

您可以像这样修改文件名:

#assuming you want to add mask before the extension
newfilename="${filename%%.*}_mask${filename#*.}"
echo "$newfilename"

${filename%%.*} is the part of $filename without extension

$ {filename %%。*}是没有扩展名的$ filename的一部分

${filename#*.} is the extension of $filename

$ {filename#*。}是$ filename的扩展名

#3


If you want to iterate only over files, then:

如果您只想对文件进行迭代,那么:

find <your-dir> -type f | xargs <your-cmd>

For example if you wanted to change access rights of only files in a current directory (but leave all the directories untouched):

例如,如果您只想更改当前目录中文件的访问权限(但保持所有目录不变):

find . -type f | xargs -n 1 chmod  u+rw

The -n 1 part tells xargs to invoke chmod for each directory separately (which is not the most efficient in this case, but you should get the idea).

-n 1部分告诉xargs分别为每个目录调用chmod(在这种情况下这不是最有效的,但你应该明白这一点)。

#4


There are several ways:

有几种方法:

  1. With xargs

xargs is useful for take a list from stdin and use each of them with a command, example:

xargs对于从stdin获取列表并使用命令使用每个列表非常有用,例如:

    ls yourdir/ | xargs yourcmd
  1. With a for loop
  2. 带有for循环

Loop can be use with a list of words or with a wildcard, example:

循环可以与单词列表或通配符一起使用,例如:

    for i in *; do yourcmd $i ; done
    # for i in `ls youdir`; do yourcmd $i ; done # Never do that
  1. With find

find allow to do it in one command, example (from GNU find man):

find允许在一个命令中执行它,例如(来自GNU find man):

find . -type f -exec file '{}' \;

Runs 'file' on every file in or below the current directory. Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation. The semicolon is simi- larly protected by the use of a backslash, though ';' could have been used in that case also.

在当前目录中或下面的每个文件上运行“文件”。请注意,大括号用单引号括起来,以保护它们不被解释为shell脚本标点符号。分号通过使用反斜杠得到了相似的保护,但是';'也可以在那种情况下使用。

#1


for file in *;
do
    echo $file
done

#2


Something like this might help you get started:

这样的事情可能会帮助你开始:

for file in /home/directory/*; do
filename=${file##*/}
echo "$filename"
##execute command here with $filename
done

If there are folders too in that directory then you will need to check for files:

如果该目录中也有文件夹,则需要检查文件:

add this line immediately after for..do:

在for..do之后立即添加此行:

[[ ! -f $file ]] && continue

If you want to ignore symbolic links, then:

如果要忽略符号链接,则:

[[ ! -f $file || -L $file ]] && continue

Additional (according to comment):

附加(根据评论):

You can check if a string (mask) is in the file name or not with:

您可以使用以下命令检查文件名中是否包含字符串(掩码):

if [[ $filename == *mask* ]];then
echo it's there
else
echo It's not there
fi

You can modify the filename like this:

您可以像这样修改文件名:

#assuming you want to add mask before the extension
newfilename="${filename%%.*}_mask${filename#*.}"
echo "$newfilename"

${filename%%.*} is the part of $filename without extension

$ {filename %%。*}是没有扩展名的$ filename的一部分

${filename#*.} is the extension of $filename

$ {filename#*。}是$ filename的扩展名

#3


If you want to iterate only over files, then:

如果您只想对文件进行迭代,那么:

find <your-dir> -type f | xargs <your-cmd>

For example if you wanted to change access rights of only files in a current directory (but leave all the directories untouched):

例如,如果您只想更改当前目录中文件的访问权限(但保持所有目录不变):

find . -type f | xargs -n 1 chmod  u+rw

The -n 1 part tells xargs to invoke chmod for each directory separately (which is not the most efficient in this case, but you should get the idea).

-n 1部分告诉xargs分别为每个目录调用chmod(在这种情况下这不是最有效的,但你应该明白这一点)。

#4


There are several ways:

有几种方法:

  1. With xargs

xargs is useful for take a list from stdin and use each of them with a command, example:

xargs对于从stdin获取列表并使用命令使用每个列表非常有用,例如:

    ls yourdir/ | xargs yourcmd
  1. With a for loop
  2. 带有for循环

Loop can be use with a list of words or with a wildcard, example:

循环可以与单词列表或通配符一起使用,例如:

    for i in *; do yourcmd $i ; done
    # for i in `ls youdir`; do yourcmd $i ; done # Never do that
  1. With find

find allow to do it in one command, example (from GNU find man):

find允许在一个命令中执行它,例如(来自GNU find man):

find . -type f -exec file '{}' \;

Runs 'file' on every file in or below the current directory. Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation. The semicolon is simi- larly protected by the use of a backslash, though ';' could have been used in that case also.

在当前目录中或下面的每个文件上运行“文件”。请注意,大括号用单引号括起来,以保护它们不被解释为shell脚本标点符号。分号通过使用反斜杠得到了相似的保护,但是';'也可以在那种情况下使用。