是否有某些命令可以在目录中搜索文件,并将结果输出到文件中,并在找到的文件名前加上前缀文本?
例如,我有一个包含这些文件的目录:
sound1
sound2
sound3
…
然后发出命令搜索目录并将结果写入带有前缀的文本文件,例如
media sound1
media sound2
media sound3
…
附加问题
有没有办法将“media1”、“media 2”等(而不是仅仅“media”)写入现有文本文件,而不删除该文本文件中之前的内容?
media1 sound1
media2 sound2
media3 sound3
…
答案1
这应该有帮助:
find /path/to/sound/files -type f -name "sound[0-9]" -printf 'media %f\n' > file.txt
信息:
sound[0-9]
:查找名称以sound
数字结尾的文件
-printf 'media %f\n'
:使用媒体前缀格式化文件名。
> file.txt
:将其发送到名为file.txt的文件。
答案2
简单for
循环怎么样?
for i in *; do echo media $i >> text_file; done
解释
*
– 扩展到当前目录下的每个文件echo media $i
– 打印“media”和当前处理的文件名>> text_file
– 将输出重定向到名为附加的echo
文件text_file
例子
$ ls
sound1 sound2 sound3
$ for i in *; do echo media $i >> text_file; done
$ cat text_file
media sound1
media sound2
media sound3
附加问题
k=0; for i in *; do ((k++)); echo media$k $i >> text_file; done
或者非常许多文件(稍快一些):
j=text_file; k=0; for i in *; do if [[ "$i" != "$j" ]]; then ((k++)); echo media$k $i; fi; done > "$j"
解释
k=0
– 定义变量k
并将其设置为0
((k++))
– 增加$k
一
例子
$ ls
sound1 sound2 sound3
$ k=0; for i in *; do ((k++)); echo media$k $i >> text_file; done
$ cat text_file
media1 sound1
media2 sound2
media3 sound3
答案3
您可以find
按照以下方式使用命令:
find . ! -name 'sound.txt' -type f -exec sh -c 'echo "media $(basename {}) "' \; > sound.txt
解释:
第一个参数是目录的路径,在示例中这是当前目录
.
,但您可以将其更改为/any/desired/path/
。! -name 'sound.txt'
- 表示带有名称的项目sound.txt
将被省略。-type f
- 表示只会查找文件。-exec <command> \;
- 指示find
执行的命令<command>
。{}
-exec
是-之前整个命令的输出参数find . ! -name 'sound.txt' -type f
。sh -c 'echo "media $(basename {}) "'
是<command>
将要执行的:sh -c
/bin/sh
— 在shell中执行命令;'echo "media $(basename {}) "'
- 要执行的命令:echo "<something>"
- 输出<something>
至标准输出;media
— 只是一个字符串;$(<some command>)
- 将结果<some command>
视为字符串;basename {}
- 仅打印文件名而不打印其路径,其中{}
包含由生成的完整文件名的变量find . ! -name 'sound.txt' -type f
最后
>
重定向 STDOUT;sound.txt
是 STDOUT 将被重定向到的文件的名称。
根据评论更新。评论中提出了两条简化上述命令的建议:
初始命令:
find . ! -name 'sound.txt' -type f -exec sh -c 'echo "media $(basename {}) "' \;
甜品建议:
find . ! -name 'sound.txt' -type f -exec sh -c 'echo media ${0##*/}' {} \;
Steeldriver 的建议:
find . ! -name 'sound.txt' -type f -printf 'media %f\n'
使用示例。假设我们有一个具有以下结构的目录:
$ tree .
.
├── sound
├── sound1
├── sound2
├── sound3
├── sound4
├── sound5
├── sound99
└── soundd
上述每个命令的输出将彼此相同:
$ find . ! -name 'sound.txt' -type f -printf 'media %f\n'
media sound1
media soundd
media sound3
media sound5
media sound2
media sound
media sound99
media sound4
附加题。根据奖励问题,该find
命令不是最佳选择,但其输出可以通过管道 ( |
) 传输到另一个命令或循环。以下是两种情况:
第一种情况是我们只想计算
media#
结果:find . ! -name 'sound.txt' -type f -printf 'media %f\n' | sort | \ while read -r i; do \ count=$((count+1)); \ echo $i | sed "s/media/media$count/"; \ done
此命令的示例输出为:
$ find . ! -name 'sound.txt' -type f -printf 'media %f\n' | sort | while read -r i; do count=$((count+1)); echo $i | sed "s/media/media$count/"; done media1 sound media2 sound1 media3 sound2 media4 sound3 media5 sound4 media6 sound5 media7 sound99 media8 soundd
另一种情况是,我们想分配每个
sound#
文件到其media
前缀。由于示例环境中有两个文件的名称中没有任何数字(sound
,soundd
),因此我们将为它们添加唯一编号,因此前缀将是media/#
:find . ! -name 'sound.txt' -type f -printf 'media %f\n' | sort | \ while read -r i; do \ number=$(echo $i | grep -Eo '[0-9]+'); \ if [ -z $number ]; then \ count=$((count+1)); number="\/$count"; \ fi; \ echo $i | sed "s/media/media$number\t/"; \ done
或者我们可以使用这个更简单的语法:
find . ! -name 'sound.txt' -type f -printf 'media %f\n' | sort | \ while read -r i; do \ number=$(echo $i | grep -Eo '[0-9]+'); \ [ -z $number ] && count=$((count+1)) && number="\/$count"; \ echo $i | sed "s/media/media$number\t/"; done
此命令的示例输出为:
$ find . ! -name 'sound.txt' -type f -printf 'media %f\n' | sort | while read -r i; do number=$(echo $i | grep -Eo '[0-9]{1,99}'); [ -z $number ] && count=$((count+1)) && number="\/$count"; echo $i | sed "s/media/media$number\t/"; done media/1 sound media1 sound1 media2 sound2 media3 sound3 media4 sound4 media5 sound5 media99 sound99 media/2 soundd
提示:
答案4
尝试这个脚本:
#!/bin/bash
dir=`find /home/username/ -name script_test`
ls $dir > test.txt
sed -i -e 's/^/media /' test.txt