2

我想知道是否可以使用 AWK 打印文件中的所有行,然后选择文件中的这些列之一以使用以下命令散列该值:

openssl dgst -sha1 | sed 's/^.* //'

我目前正在使用读取命令,但它似乎写得非常慢。这是我目前所拥有的:

while IFS="," read -ra line;
do
    if [ "${line[1]}" != "" ]; then
        echo -n "${line[*]}, Hash Value:"; echo "${line[1]}" | openssl dgst -sha1 | sed 's/^.* //'
    else
        if [ "${line[1]}" == "" ]; then
            echo "${line[*]}, Hash Value: None";
        fi
    fi
done

所以我想我最终要说的是,我怎样才能使用 AWK 来打印所有行并在特定列上执行命令?希望加快阅读过程。另外,是否可以使用 AWK 打印目录中所有文件的列?

多谢你们!

更新

下面是包含将所有文本文件转换为 DOS 到 UNIX 格式的代码。下面是 unix.txt 的一些输出。最后,下面是我的脚本。

dos2unix

$ dos2unix *.txt
dos2unix: converting file unix.txt to Unix format ...
dos2unix: converting file woohoo.txt to Unix format ...

unix.txt 输入

7051,95230163,-1,53200703
7051,95230163,-1,53200703
7051,95230163,-1,53200703
53200703,2286,Mon Jul 01 13:30:03 PDT 2013
53200703,2286,Mon Jul 01 13:30:03 PDT 2013
53200703,2286,Mon Jul 01 13:30:03 PDT 2013

unix.txt 输出

$ ./trial.sh < unix.txt
7051,95230163,-1,53200703, Hash Value: c9b674deec9973f4d0feb83433d6db0b4ea5012a
7051,95230163,-1,53200703, Hash Value:
7051,95230163,-1,53200703, Hash Value:
53200703,2286,Mon Jul 01 13:30:03 PDT 2013, Hash Value: 2a8db89cc6f4ccdc0ce423011e869cb8b29b1003
53200703,2286,Mon Jul 01 13:30:03 PDT 2013, Hash Value:
53200703,2286,Mon Jul 01 13:30:03 PDT 2013, Hash Value:

脚本

gawk -F',' '
function hash(val, var) 
    {
    if (val == "") { 
           var = "None" 
          }
              else {
                    "echo \"" val "\" | openssl dgst -sha1" | getline var
                   sub(/.* /,"",var) 
                    }
              return var 
                    }
{ printf "%s, Hash Value: %s\n", $0, hash($2) } '

正如您所看到的,当针对 unix.txt 运行脚本时,包含第二列的值没有散列。前几行虽然是散列。不知道发生了什么,但它应该工作。

4

3 回答 3

2
$ cat input.txt         
7051,95230163,-1,53200703
7051,95230163,-1,53200703
7051,95230163,-1,53200703
53200703,2286,Mon Jul 01 13:30:03 PDT 2013
53200703,2286,Mon Jul 01 13:30:03 PDT 2013
53200703,2286,Mon Jul 01 13:30:03 PDT 2013
$                       
$ cat trial.sh
gawk -F',' '
function hash(val, var) {
    if (val == "") { 
        var = "None" 
    }
    else {
        cmd = "echo \"" val "\" | openssl dgst -sha1"
        cmd | getline var
        close(cmd)
        sub(/.* /,"",var) 
    }
    return var 
}
{ printf "%s, Hash Value: %s\n", $0, hash($2) }
'
$ 
$ ./trial.sh < input.txt
7051,95230163,-1,53200703, Hash Value: c9b674deec9973f4d0feb83433d6db0b4ea5012a
7051,95230163,-1,53200703, Hash Value: c9b674deec9973f4d0feb83433d6db0b4ea5012a
7051,95230163,-1,53200703, Hash Value: c9b674deec9973f4d0feb83433d6db0b4ea5012a
53200703,2286,Mon Jul 01 13:30:03 PDT 2013, Hash Value: 2a8db89cc6f4ccdc0ce423011e869cb8b29b1003
53200703,2286,Mon Jul 01 13:30:03 PDT 2013, Hash Value: 2a8db89cc6f4ccdc0ce423011e869cb8b29b1003
53200703,2286,Mon Jul 01 13:30:03 PDT 2013, Hash Value: 2a8db89cc6f4ccdc0ce423011e869cb8b29b1003

请注意,上面是 GNU-awk 特定的,因为它使用协进程将 shell 命令的输出通过管道传输到 getline 读取。

另外,既然我看到您的示例输入包含许多重复项,那么通过仅在第一次计算哈希值并随后使用它来避免重复键字段的外部命令和管道,这可能会更有效:

$ cat trial.sh               
gawk -F',' '
function hash(val) {
    if ( !(val in map) ) {
        if (val == "") { 
            map[val] = "None" 
        }
        else {
            cmd = "echo \"" val "\" | openssl dgst -sha1"
            cmd | getline map[val]
            close(cmd)
            sub(/.* /,"",map[val])
        }
    }
    return map[val]
}
{ printf "%s, Hash Value: %s\n", $0, hash($2) }
'

是的,当然,您可以使用 awk 从目录中的所有文件中打印您想要的任何内容:

awk '{ print <whatever> }' /dir/*
于 2013-08-20T17:14:54.540 回答
2

可以从awk. 您只需要正确引用,如下所示:

echo "123" | awk '{ print $0 | "openssl dgst -sha1 | sed '"'s/^.* //'"'" }'

输出:

a8fdc205a9f19cc1c7507a60c4f01b13d11d7fd0
于 2013-08-20T14:11:03.690 回答
1

通常,您会执行以下操作:

cat file
awk '{print $2}' file | openssl dgst -sha1 | sed 's/^.* //'

这用于cat将文件中的所有行复制到标准输出,然后用于awk打印第 2 列中的值,该列通过管道传输到openssland sed。你有理由不能这样做吗?

如果输入来自命令(所以你不能重读它),你必须更加努力,但你明确地说“来自文件”,所以我认为这不是问题。

于 2013-08-20T15:00:07.340 回答