Bash 拆分文件名并在下划线的第一次和最后一次出现之间获取元素

Bash 拆分文件名并在下划线的第一次和最后一次出现之间获取元素,bash,for-loop,split,substring,Bash,For Loop,Split,Substring,我试图在for循环中拆分许多文件夹名称,并在filename的第一个下划线和最后一个下划线之间提取元素。文件名可以类似于ENCSR000AMA\u HepG2\u CTCF或ENCSR000ALA\u内皮细胞\u脐静脉\u CTCF 我的问题是,文件夹名称的下划线总数不同,因此我不能使用以下内容: IN=$d folderIN=(${IN//_/ }) tf_name=${folderIN[-1]%/*} #get last element which is the TF name cell_l

我试图在for循环中拆分许多文件夹名称,并在filename的第一个下划线和最后一个下划线之间提取元素。文件名可以类似于ENCSR000AMA\u HepG2\u CTCF或ENCSR000ALA\u内皮细胞\u脐静脉\u CTCF

我的问题是,文件夹名称的下划线总数不同,因此我不能使用以下内容:

IN=$d
folderIN=(${IN//_/ })
tf_name=${folderIN[-1]%/*} #get last element which is the TF name
cell_line=${folderIN[-2]%/*}; #get second last element which is the cell line
dataset_name=${folderIN[0]%/*}; #get first element which is the dataset name
单元格线可以是一个或多个用下划线分隔的单词,但始终在第一个和最后一个下划线之间


有什么帮助吗?

只需在两步bash参数扩展中执行此操作,因为与
zsh
或其他shell不同,
bash
不支持嵌套参数扩展

“${string%.*}”
在上次出现“.”之后删除所有内容,
“${tempString%.*.}”
从开始到第一次出现“.”删除所有内容

string="ENCSR000ALA_endothelial_cell_of_umbilical_vein_CTCF"
tempString="${string%_*}"
printf "%s\n" "${tempString#*_}"
endothelial_cell_of_umbilical_vein
再比如,

string="ENCSR000AMA_HepG2_CTCF"
tempString="${string%_*}"
printf "%s\n" "${tempString#*_}"
HepG2
您可以修改此逻辑以应用于文件夹中的每个文件名。

可以使用正则表达式

extract_words() {
    [[ "$1" =~ ^([^_]+)_(.*)_([^_]+)$ ]] && echo "${BASH_REMATCH[2]}"
}

while read -r from_line
do
    extracted=$(extract_words "$from_line")
    echo "$from_line" "[$extracted]"
done < list_of_filenames.txt
extract_words(){
[[“$1”=~^([^]+)(+.*)(+[^]+)$]]和&echo“${BASH\u重新匹配[2]}”
}
从_行读取-r时
做
提取=$(提取单词“$自\u行”)
回显“$from_line”“[$extracted]”
完成
编辑:我将“提取”移到了一个单独的bash函数中,以便重用和轻松修改更复杂的情况,如:

extract_words() {
        perl -lnE 'say $2 if /^([^_]+)_(.*)_([^_]+)$/' <<< "$1"
}
extract_words(){

perl-lnE‘如果/^([^ _]+)(+.*)([^ _]+)$/’您不需要命令替换,就说$2;让
提取单词
调用
[
命令;
BASH_重新匹配
是全局设置的,这样您就可以编写
提取单词“$from_line”&&extracted=${BASH_重新匹配[2]}
@chepner当然可以。但只有在您使用内置bash正则表达式的情况下。如果有人用一些
awk
perl
(对于更复杂的场景)替换
extract\u words的
内容,则需要使用命令替换。正如我所写的,它是为方便修改而设计的。(而且因为替换实际上调用了bash函数,所以不会有任何伤害):d更改为
extract_words
的人可能会遇到这个问题。我不认为在不必要的情况下,适应未来对代码的修改是值得的。@chepner好的,这很公平。主要问题,例如回答OP的问题,如何提取想要的字符串,得到了回答。可能是don使用bash_正则表达式,一次完成。所有的绒毛都取决于读者…:)