使用awk时如何防止换行

时间:2014-02-20 23:39:40

标签: variables awk newline

我已经看到了这个问题的几个变体,但没有一个答案对我的特定情况有帮助。

我正在尝试加载一些文件,为文件名添加一列。只有当我将文件名作为第一列时,这才能正常工作。如果我把文件名列放在最后(我想要的地方),它会在$ 0和我无法停止的其余打印之间创建一个新行。

for f in "${FILE_LIST[@]}"
do
awk '{ print FILENAME,"\t",$0 } ' ${DEST_DIR_FILES}/$f > tmp ## this one works
awk '{ print $0,"\t",FILENAME } ' ${DEST_DIR_FILES}/$f > tmp ## this one does not work
mv tmp ${DEST_DIR_FILES}/$f
done > output 

示例数据:

- 我从这开始:

A       B       C
aaaa    bbbb    cccc
1111    2222    3333

- 我想要这个(带文件名的新列):

A       B       C       FILENAME
aaaa    bbbb    cccc    FILENAME
1111    2222    3333    FILENAME            

- 我得到了这个(\ t和文件名在新行上):

A       B       C
        FILENAME
aaaa    bbbb    cccc
        FILENAME
1111    2222    3333
        FILENAME

加分问题 我正在使用一个变量来传递文件名,但它正在放置整个路径。只打印文件名的最佳方法是什么(没有路径)〜或者〜使用保存路径的变量去掉文件路径?

1 个答案:

答案 0 :(得分:2)

由于awk脚本在语法上是正确的,因此几乎可以肯定是行结束问题。我怀疑"${FILE_LIST[@]}"中的文件来自Windows框,并且有\r\n行结尾。要确认给定文件的行结尾,您可以对每个文件运行file命令,例如 file filename

# create a test file
$ echo test > foo      

# use unix2dos to convert to Windows style line endings
$ unix2dos foo       
unix2dos: converting file foo to DOS format ...

# Use file to confirm line endings
$ file foo       
foo: ASCII text, with CRLF line terminators

# Convert back to Unix style line endings
$ dos2unix foo
dos2unix: converting file foo to Unix format ...

$ file foo
foo: ASCII text

要将文件转换为Unix样式行结尾\n,请运行以下命令:

$ for "f" in "${FILE_LIST[@]}"; do; dos2unix "$f"; done

<强>解释

FILENAME是该行的第一个字符串时,回车符\r实际上没有任何效果,因为我们已经在行的开头。当我们尝试在任何其他字符之后打印FILENAME时,我们会看到我们带到下一行开头的效果,然后打印TAB,然后打印FILENAME

旁注:

Awk具有变量OFS,用于设置输出字段分隔符:

$ awk '{print $0,"\t",FILENAME}' file

可以改写为:

$ awk '{print $0,FILENAME}' OFS='\t' file

奖励回答

I.M.O 剥离文件路径的最佳方法是使用实​​用程序basename

$ basename /tmp/foo
foo

使用command substitution

$ awk '{print FILENAME}' $(basename /tmp/foo)
foo