使用 shell 查找和替换文件中的换行符和单词
Posted
技术标签:
【中文标题】使用 shell 查找和替换文件中的换行符和单词【英文标题】:Find and replace a new line character and a word in a file using shell 【发布时间】:2021-01-12 12:55:54 【问题描述】:我有一个文件 sample.txt,其内容是
line-1
Generic-text-1 line-2
Generic-text-2 line-3
line-2
Generic-text-1 line-2
Generic-text-2 line-3
我想将文件的内容更改为 CSV,以便将内容转换为如下所示。
line-1,line-2,line-3
line-2,line-2,line-3
我正在尝试使用 sed 命令,但不适用于换行符。
sed -i 's/\nGeneric-text-1/,/g' sample.txt
sed -i 's/\nGeneric-text-2/,/g' sample.txt
提前致谢
【问题讨论】:
awk '$0=$NF' sample.txt | paste -d ',' - - -
?
您需要更多详细信息。我们可以猜测“line-1”和“Generic-text-1”之间的区别特征是该行中存在多个非空白字符串,但这只是一个猜测。
【参考方案1】:
这可能对你有用(GNU sed):
sed -E ':a;$!N;s/\n\S+\s/,/;ta;P;D' file
收集行,用逗号替换换行符、第一个字段及其分隔符。当匹配失败时,打印第一行,删除并重复。
更详细的解释:
-E
命令行选项扩展了正则表达式。在这种情况下,允许使用简写 +
而不是 \+
。
:a
是一个占位符 a
,它允许在此时恢复执行 sed 命令(稍后与 ta
结合使用)。
$!N
只要当前行不是文件$!
中的最后一行,就将下一行N
追加到模式空间中的当前行。模式空间是执行 sed 命令的缓冲区。
s/\n\S+\s/,/
是替换命令,其中 ,
将替换为匹配的换行符,后跟一个或多个非空白字符,后跟一个空白字符,即附加行开头的单词,后跟一个至少一个空格。
ta
如果替换成功则将代码执行跳转到占位符 a
即返回 2 条指令。
P
此时最后一次替换失败,这会打印到并包括模式空间中的第一个换行符。
D
这将删除模式空间中的第一个换行符(包括第一个换行符)。但是,与 d
命令重新启动 sed 循环并将下一行读入模式空间不同,此命令仅在当前模式空间为空时才会这样做。如果它包含值,它会在第一个 sed 命令处恢复,在这种情况下是在命令 :a
。
因此 sed 程序会蚕食文件,创建和打印/删除自己制作的行。
或者在紧要关头:
sed -z 's/\n\S\+ /,/g' file
或:
awk 'gsub(/\n\S+ /,",")1' RS= file
【讨论】:
如果您能向我解释您给出的第一个解决方案的选项,我将不胜感激:) sed -E ':a;$!N;s/\n\S+\s/, /;ta;P;D' 文件 非常感谢,非常感谢。【参考方案2】:使用awk
,你可以这样做:
awk -v OFS=, 'NF > 1
printf "%s", OFS $NF
NF == 1
if (NR>1)
print ""
printf "%s", $1
END
print ""
' file
line-1,line-2,line-3
line-2,line-2,line-3
【讨论】:
【参考方案3】:您能否尝试在 GNU awk
中使用所示示例进行跟踪、编写和测试。
awk '
BEGIN OFS=","
/^line/
if(val)
print val
val=$1
next
val=(val?val OFS:"")$NF
END
if(val)
print val
' Input_file
【讨论】:
【参考方案4】:使用awk
,只打印每行的最后一个单词。使用逗号分隔符合并成一行,将两个单词行之间的所有单词。
awk 'NF==1 && NR!=1print r; r="" r = (r? r "," $NF: $NF) END print r' file
输出:
line-1,line-2,line-3
line-2,line-2,line-3
【讨论】:
以上是关于使用 shell 查找和替换文件中的换行符和单词的主要内容,如果未能解决你的问题,请参考以下文章