在 for 循环中使用 find 将部分文件名提取为变量 (bash)
Using find within a for loop to extract portion of file names as a variable (bash)
我有许多文件,它们的名称中包含一条有用的信息,我想将其提取为变量并在后续步骤中使用。文件名的结构是 samplename_usefulbit_junk。我试图使用文件名的可预测部分 (samplename) 遍历这些文件,将整个名称存储在一个变量中,并使用 sed
提取有用的位。这是行不通的。
samples="sample1 sample2 sample3"
for i in $samples; do
filename="$(find ./$FILE_DIR -maxdepth 1 -name '$(i)*' -printf '%f\n')"
usefulbit="$(find ./$FILE_DIR -maxdepth 1 -name '$(i)*' -printf '%f\n' | sed 's/.*samplename//g' | sed 's/junk.*//g')"
(More steps using $usefulbit or $(usefulbit) or ${usefulbit} or something)
done
find ./$FILE_DIR -maxdepth 1 -name 'sample1*' -printf '%f\n'
和 find ./$FILE_DIR -maxdepth 1 -name "sample1*" -printf '%f\n'
都有效,但是括号、大括号或单引号、双引号或反引号的组合都无法使循环起作用。这是哪里出了问题?
试试这个:
for file in `ls *_*_*.*`
do
echo "Full file name is: $file"
predictable_portion_filename=${file_%%_*}
echo "predictable portion in the filename is: ${predictable_portion_filename}"
echo "---"
done
PS: $variable or ${variable} or "${variable}" or "$variable" 不同于 $(variable) 在最后一种情况下,$( ... ) 使得一个 sub-shell 并将其中的任何内容视为命令,即 $(variable) 将使 sub-shell 执行名为 variable[=11= 的命令]
代替 ls __.,您还可以使用(以递归方式查找具有该标准文件名的所有文件): ls -1R *_*_*.*
除了使用 ${file%%_*} 您还可以使用:echo ${file} | cut -d'_' -f1 以获得可预测的值。您也可以使用其他各种方式(awk、sed/等)。
对不起,我无法使用 bash,我可以向您展示另一种方法吗?这是我正在开发的 shell (lua-shell),以及一个演示作为您案例的解决方案:
wws$ `ls ./demo/2
sample1_red_xx.png sample2_green_xx.png sample3_blue_xx.png
wws$ source ./demo/2.lua
sample1_red_xx.png: red
sample2_green_xx.png: green
sample3_blue_xx.png: blue
wws$
我真的很想知道你的整个计划,除非你需要 bash 作为唯一的工具......
呃,我忘记粘贴脚本了:
samples={"sample1", "sample2", "sample3"}
files = lfs.collect("./demo/2")
function get_filename(prefix)
for i, file in pairs(files) do
if string.match(file.name, prefix) then return file.name end
end
end
for i = 1, #samples do
local filename = get_filename(samples[i])
vim:set(filename)
:f_lvf_hy
print(filename ..": ".. vim:clipboard())
end
'get_filename()'似乎有点冗长...我还没有完成 lfs 组件。
我不确定用我的最终解决方案回答我自己的问题是否是适当的 Whosebug 礼节,但这最终对我有用:
for i in directory/*.ext; do
myfile="$i"
name="$(echo $i | sed 's!.*/!!g' | sed 's/_junk*.ext//g')"
some other steps
done
这样一开始,我的文件名已经是一个变量(在一个变量中?),而不必纠结于 find
及其强烈的意见。它还使我不必列出样本名称。
第一个 sed
删除目录 /,第二个删除文件名和扩展名的末尾,留下一个变量 $name,我在后续步骤中生成其他文件时将其用作前缀。简单多了!
我有许多文件,它们的名称中包含一条有用的信息,我想将其提取为变量并在后续步骤中使用。文件名的结构是 samplename_usefulbit_junk。我试图使用文件名的可预测部分 (samplename) 遍历这些文件,将整个名称存储在一个变量中,并使用 sed
提取有用的位。这是行不通的。
samples="sample1 sample2 sample3"
for i in $samples; do
filename="$(find ./$FILE_DIR -maxdepth 1 -name '$(i)*' -printf '%f\n')"
usefulbit="$(find ./$FILE_DIR -maxdepth 1 -name '$(i)*' -printf '%f\n' | sed 's/.*samplename//g' | sed 's/junk.*//g')"
(More steps using $usefulbit or $(usefulbit) or ${usefulbit} or something)
done
find ./$FILE_DIR -maxdepth 1 -name 'sample1*' -printf '%f\n'
和 find ./$FILE_DIR -maxdepth 1 -name "sample1*" -printf '%f\n'
都有效,但是括号、大括号或单引号、双引号或反引号的组合都无法使循环起作用。这是哪里出了问题?
试试这个:
for file in `ls *_*_*.*`
do
echo "Full file name is: $file"
predictable_portion_filename=${file_%%_*}
echo "predictable portion in the filename is: ${predictable_portion_filename}"
echo "---"
done
PS: $variable or ${variable} or "${variable}" or "$variable" 不同于 $(variable) 在最后一种情况下,$( ... ) 使得一个 sub-shell 并将其中的任何内容视为命令,即 $(variable) 将使 sub-shell 执行名为 variable[=11= 的命令]
代替 ls __.,您还可以使用(以递归方式查找具有该标准文件名的所有文件): ls -1R *_*_*.*
除了使用 ${file%%_*} 您还可以使用:echo ${file} | cut -d'_' -f1 以获得可预测的值。您也可以使用其他各种方式(awk、sed/等)。
对不起,我无法使用 bash,我可以向您展示另一种方法吗?这是我正在开发的 shell (lua-shell),以及一个演示作为您案例的解决方案:
wws$ `ls ./demo/2
sample1_red_xx.png sample2_green_xx.png sample3_blue_xx.png
wws$ source ./demo/2.lua
sample1_red_xx.png: red
sample2_green_xx.png: green
sample3_blue_xx.png: blue
wws$
我真的很想知道你的整个计划,除非你需要 bash 作为唯一的工具...... 呃,我忘记粘贴脚本了:
samples={"sample1", "sample2", "sample3"}
files = lfs.collect("./demo/2")
function get_filename(prefix)
for i, file in pairs(files) do
if string.match(file.name, prefix) then return file.name end
end
end
for i = 1, #samples do
local filename = get_filename(samples[i])
vim:set(filename)
:f_lvf_hy
print(filename ..": ".. vim:clipboard())
end
'get_filename()'似乎有点冗长...我还没有完成 lfs 组件。
我不确定用我的最终解决方案回答我自己的问题是否是适当的 Whosebug 礼节,但这最终对我有用:
for i in directory/*.ext; do
myfile="$i"
name="$(echo $i | sed 's!.*/!!g' | sed 's/_junk*.ext//g')"
some other steps
done
这样一开始,我的文件名已经是一个变量(在一个变量中?),而不必纠结于 find
及其强烈的意见。它还使我不必列出样本名称。
第一个 sed
删除目录 /,第二个删除文件名和扩展名的末尾,留下一个变量 $name,我在后续步骤中生成其他文件时将其用作前缀。简单多了!