查找不同目录中的文件并对文件名进行操作

时间:2017-07-12 20:15:30

标签: linux bash shell

$ ls /tmp/foo/
file1.txt  file2.txt
$ ls /tmp/bar/
file20.txt
$ ls /tmp/foo/file*.txt | grep -o -E '[0-9]+'  | sort -n | paste -s -d,
1,2

如何从两个目录中获取文件名中的数字?在上面的例子中,我需要得到1,2,20,它在bash shell中。

更新:

$ ls /tmp/foo/file*.txt /tmp/bar/file*.txt /tmp/jaz99/file*.txt /tmp/nah/file*.txt | grep -o -E '[0-9]+'  | sort -n | paste -s -d,
ls: cannot access /tmp/nah/file*.txt: No such file or directory
1,2,20,30,99

在这种情况下,它不应该打印99(因为它与*不匹配),如果找不到文件,则不应该打印错误。

2 个答案:

答案 0 :(得分:2)

您可以使用输出为find的循环完成此操作:

s=

# run a loop using find command in a process substitution
while IFS= read -d '' -r file; do
   file="${file##*/}"      # strip down all directory paths
   s+="${file//[!0-9]/},"  # remove all non-numeric characters and append comma
done < <(find /tmp/{foo,bar,nah,jaz99} -name '*.txt' -print0 2>/dev/null)

echo "${s%,}"              # remove last comma from string

<强>输出

1,2,20,30

答案 1 :(得分:0)

这是我对此的看法。使用数组。无需使用sed或awk等外部工具或查找。

#!/usr/bin/env bash

declare -a a=()

for f in /tmp/{foo,bar,nah}/file*.txt; do
  [[ $f =~ .*file([0-9]+).* ]]
  a+=( ${BASH_REMATCH[1]} )
done

IFS=,
echo "${a[*]}"

[[...]]表达式使用正则表达式组件填充$BASH_REMATCH数组。您可以使用它来提取数字并将它们放在一个新的临时数组中,您可以使用$IFS使用逗号分隔符表示。

结果:

$ mkdir /tmp/foo /tmp/bar
$ touch /tmp/foo/file{1,2}.txt /tmp/bar/file20.txt
$ ./doit
1,2,20