如何使用sed在文件中的每一行之前插入一行,原始行的内容由字符串围绕?

时间:2016-11-09 14:01:31

标签: bash sed

我正在尝试使用sed(GNU sed版本4.2.1)在文件中的每一行之前插入一行,该行的内容由字符串围绕。

输入:

truncate table ALPHA;
truncate table BETA;
delete from TABLE_CHARLIE where ID=1;

预期结果:

SELECT 'truncate table ALPHA;' from dual;
truncate table ALPHA;
SELECT 'truncate table BETA;' from dual;
truncate table BETA;
SELECT 'delete from TABLE_CHARLIE where ID=1;' from dual;
delete from TABLE_CHARLIE where ID=1;

我试图使用&符号(&)特殊字符,但这似乎不起作用。如果我在替换字符串上放了&符之后的任何内容,则输出不正确。

尝试1:

sed -e "s/\(.*\)/SELECT '&\n&/g" input.txt

output:
SELECT 'truncate table ALPHA;
truncate table ALPHA;
SELECT 'truncate table BETA;
truncate table BETA;
SELECT 'delete from TABLE_CHARLIE where ID=1;
delete from TABLE_CHARLIE where ID=1;

使用上面的代码,我按预期得到了SELECT ',但是一旦我尝试将' from dual;添加到字符串的右侧,就会出现问题。

尝试2:

sed -e "s/\(.*\)/SELECT '&' from dual;\n&/g"  input.txt

output:
' from dual;cate table ALPHA;
truncate table ALPHA;
' from dual;cate table BETA;
truncate table BETA;
SELECT 'delete from TABLE_CHARLIE where ID=1;' from dual;

4 个答案:

答案 0 :(得分:5)

您可以利用保留空间临时存储原始行。

sed "h;s/.*/'SELECT '&' from dual;/;p;g" input.txt

或更可读:

sed "
h
s/.*/'SELECT '&' from dual;/
p
g" input.txt

这是命令的细分。

  1. 首先,输入的每一行都放在模式空间中。
  2. h命令将模式空间的内容复制到 hold 空间。
  3. s命令对模式空间执行替换。 &表示匹配的内容。此命令使保留空间不受影响。
  4. p命令将模式空间的内容输出到标准输出。
  5. g命令将保留空间的内容复制到模式空间。
  6. 默认情况下,在读取下一个输入行之前,模式空间的内容将写入标准输出。
  7. 正如Glenn Jackman指出的那样,您可以将p;g替换为G。这会在模式空间中构建一个两行值,然后打印,而不是打印两个单独的模式空间。

    sed "h;s/.*/'SELECT '&' from dual;/;G" input.txt
    

    此外,您可以在sed命令中添加注释,以便您可以了解线路噪声的影响:),如果这是在脚本中。

    sed " 
    # The input line is first copied to the pattern space
    
    h                               # Copy the pattern space to the hold space
    s/.*/'SELECT '&' from dual;/    # Modify the pattern space
    p                               # Print the (modified) pattern space
    g                               # Copy the hold space to the pattern space
    
    # The output of the pattern space (the original input line) is now printed
    " input.txt
    

答案 1 :(得分:1)

您的第二次尝试适用于sed的4.2.1和4.2.2版本。当我尝试使用Windows行结尾(换行和回车)保存输入文件时,我收到了相同的无效输入。

在运行sed命令之前,在输入文件中使用此命令:

tr -d '\15\32' < winfile.txt > unixfile.txt

或者按照您的建议,只需使用dos2unix实用程序。

答案 2 :(得分:1)

如果你正在寻找sed的替代品,这些工作:

awk '{printf "SELECT '\''%s'\'' from dual;\n%s\n", $0, $0}' file
perl -lpe "print qq{SELECT '\$_' from dual;}" file

答案 3 :(得分:0)

以下是使用awk -v PRE="SELECT '" -v SU="' from dual;" '{print PRE$0SU; print}'`

的方法
JQuery