我有以下格式的文本文件:
label1-label1/label2 label1
label3-label3/label4 label3
label5-label5/label6 label5
我要生成以下格式的输出:
label1/label2
label3/label4
label5/label6
我不能使用'-'
或'/'
作为分隔符,因为它们也是标签的一部分。
我尝试使用awk
和sed
命令从文件中提取$1
和$2
,但无法弄清楚如何提供$2
作为要从$1
替换的原始模式。
我考虑过使用$2
(label1)来匹配$1
(label1-label1 / label2)中的模式并对其进行修整以得到结果,label1 / label2,但不知道如何做吧。
例如: Label1:美国,Label2:纽约
输入:-
United-States-United-States/New-York United-States
输出:-
United-States/New-York
答案 0 :(得分:0)
这里是纯bash脚本的解决方案:
#!/bin/bash
while read -r line; do
attachment="${line##* }" # get last part of line
length="${#attachment}" # length of last part
printf "%s\n" "${line:length+1:-length}" # print line, shorten the start/end by last part
done < file.txt
输入(file.txt)
label1-label1/label2 label1
label3-label3/label4 label3
label5-label5/label6 label5
United-States-United-States/New-York United-States
United/States/United/States/New-York United/States
United-States-United-States-New-York United-States
United$States$United$States$New$York United$States
United*States*United*States*New*York United*States
输出
label1/label2
label3/label4
label5/label6
United-States/New-York
United/States/New-York
United-States-New-York
United$States$New$York
United*States*New*York
答案 1 :(得分:0)
好主意也是如此...虽然可以使用awk
拆分,但是使用while
循环从文件中读取信息以及将第一个组合分开也很容易从label1
到label2
到<-end
进行简单的参数扩展修剪,将所需数据分为beginning->
和'/'
分隔它们的字符。届时,您只需要从1/2 length + 1
中取出label1
,然后将其与保存的label2
组合成所需的字符串即可。
类似的东西:
while read -r label stuff; do ## read combined label, ignore 2nd string stuff
l1="${label%/*}" ## isolate label1 (l1)
l2="${label#*/}" ## isolate label2 (l2)
l1=${l1:$((${#l1}/2+1))} ## take len/2+1 of l1
echo "$l1/$l2" ## put shortened l1 and l2 together
done < file
示例输入文件
使用输入文件和文件中显示的示例:
$ cat file
label1-label1/label2 label1
label3-label3/label4 label3
label5-label5/label6 label5
United-States-United-States/New-York United-States
使用/输出示例
只需在file
所在目录的终端中选择并使用中间鼠标粘贴即可提供以下所需输出:
$ while read -r label stuff; do ## read combined label, ignore 2nd string stuff
> l1="${label%/*}" ## isolate label1 (l1)
> l2="${label#*/}" ## isolate label2 (l2)
> l1=${l1:$((${#l1}/2+1))} ## take len/2+1 of l1
> echo "$l1/$l2" ## put shortened l1 and l2 together
> done < file
label1/label2
label3/label4
label5/label6
United-States/New-York
(注意: UtLox是这里的第一个答案,因此无论出于何种考虑,都应给予优先权,这本质上是相同的方法,只是长度,除法的不同方法和加法发生
这里最简单的方法可能是,如果可以保证行的最后部分始终为label1
。如果对您的文件而言这是有效的,那么您只需要单个参数扩展即可输出所需的结果,例如
while read -r label l1; do ## read both parts of line
echo "$l1/${label#*/}" ## put l1 with trimmed label
done < file
使用/输出示例
$ while read -r label l1; do ## read both parts of line
> echo "$l1/${label#*/}" ## put l1 with trimmed label
> done < file
label1/label2
label3/label4
label5/label6
United-States/New-York
如果每行的第二部分始终是您的label1
(无需拆分'/'
之前的内容),则这是一种更简单的方法
如果您还有其他问题,请告诉我。
答案 2 :(得分:0)
使用sed:
sed 's/^\(.*\)-\1\/\(.*\) \1$/\1\/\2/' file
此匹配项:
并将其替换为:
不匹配的行将保持不变。
如果输入格式错误,则不输出:
sed '/^\(.*\)-\1\/\(.*\) \1$/!d; s//\1\/\2/' file