dmx*_*dmx 7 command-line text-processing
替换文件中的列的最简单方法是什么?基本上,我的file.txt3 列由,.
如何使用 bash 脚本更改第二列?
SveUJW24ibppfePgYeYHz7fC0,64BzZdqrYY7Tx8sbj5tmEW,yL6mCP0Do28k4EoTZUfKfqNYiIhGxxkA
xyRG8Da6kY35xeIT492Lul7xu,gTdmvjmahIOoyzmrttVMvTc1ER0bt,ne6RIM2TeMQAax1GgzL7FeDrnQyHPH1i
sxTf13KlAnjtXodJouQ9V6m5b,LzLtoEg18E1brm66dPjcHZfpI107nn4h,GUnApYwwDCZxWGZtzKzTU6sJRgHlUUfQ
7cjW5DZlXw1LYzVugbVyqfxRX,i7B4Q9w8h5anmMW87DfIBEm0AuNjbLGq,XttE1In9eZQ8puJVUriuNvx2AJAxviGf
XiLE8r9AMqy5YZQ9BbIS6m559,ToT2wbQdpNNySPxP1Tgz1,DssiszVBa05pbVDSOXNRaFXRxw0eZKHf
Sygrl5287BViOn0uQ9uCYipB1,TEYnXl6APWGbm9ckLCcHFUJzk7qS8JXH,sD2O46sbh1yVIluoyn6Zm2OKXYe05vV9
Qi6DxJ96M0hxNe4cgux3iJ1aS,LK3GHTpuo9kbmK9McRN4sFRQTGh2DU8J,wk2eF3f9xk5HowLzDIL3hCCNSmx8Uwi8
ZIX7qp5IIPekA0kzBdFR4IUQZ,9m9lEjfiotQ97s3uVN8EEP7Y1JmpgAk7,99ilfJWoJEBsKOfYI3buFfher07OCz6Y
Run Code Online (Sandbox Code Playgroud)
更新
替换为变量中的另一个字符串。让我们说var=new-sting。
实际上,我在想我可以做这样的事情:
sed "s/,[^,]*/,$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)/" file.txt
Run Code Online (Sandbox Code Playgroud)
但它没有按预期工作。我一遍又一遍地使用相同的字符串。
假设file.txt包含用逗号分为三列的文本行,并且任何地方都没有额外的逗号,因此每行正好有两个:
replacement="my string"
sed "s/,.*,/,$replacement,/" file.txt
Run Code Online (Sandbox Code Playgroud)
输出:
replacement="my string"
sed "s/,.*,/,$replacement,/" file.txt
Run Code Online (Sandbox Code Playgroud)
这将一次处理所有行,并每次用相同的值替换中间列。修改后的内容默认会打印到终端,如果你想file.txt就地修改,用 writesed -i而不是 plain sed。
如果您无论如何都需要更新每一行的替换变量(这里是每行一个新的随机字符串),您可以像这样循环遍历这些行:
while read line ; do
replacement="random number $RANDOM"
sed "s/,.*,/,$replacement,/" <<< "$line"
done < file.txt
Run Code Online (Sandbox Code Playgroud)
示例输出:
SveUJW24ibppfePgYeYHz7fC0,my string,yL6mCP0Do28k4EoTZUfKfqNYiIhGxxkA
xyRG8Da6kY35xeIT492Lul7xu,my string,ne6RIM2TeMQAax1GgzL7FeDrnQyHPH1i
sxTf13KlAnjtXodJouQ9V6m5b,my string,GUnApYwwDCZxWGZtzKzTU6sJRgHlUUfQ
7cjW5DZlXw1LYzVugbVyqfxRX,my string,XttE1In9eZQ8puJVUriuNvx2AJAxviGf
XiLE8r9AMqy5YZQ9BbIS6m559,my string,DssiszVBa05pbVDSOXNRaFXRxw0eZKHf
Sygrl5287BViOn0uQ9uCYipB1,my string,sD2O46sbh1yVIluoyn6Zm2OKXYe05vV9
Qi6DxJ96M0hxNe4cgux3iJ1aS,my string,wk2eF3f9xk5HowLzDIL3hCCNSmx8Uwi8
ZIX7qp5IIPekA0kzBdFR4IUQZ,my string,99ilfJWoJEBsKOfYI3buFfher07OCz6Y
Run Code Online (Sandbox Code Playgroud)
将此代码片段放入脚本文件中,然后将其输出重定向到一个单独的新文件(不是您从中读取的原始文件!),这可能是最简单的方法,如下所示:
bash my-replacement-script.sh > new-file.txt
Run Code Online (Sandbox Code Playgroud)
我建议一种基于 perl Bytes::Random::Secure 模块的方法,基于使用 bash修改为使用所需的大小写字母和十进制数字组合使用随机数据填充文本文件列:
perl -MBytes::Random::Secure=random_string_from -F, -ane '
BEGIN{$chars = join "", ("a".."z","A".."Z",0..9)}
$F[1] = random_string_from($chars, 32);
print join ",", @F
' file
Run Code Online (Sandbox Code Playgroud)
或者,如果你想使用你的/dev/urandom管道,一种没有外部循环的方法是使用带有 awkgetline函数的 FIFO :
制作先进先出 $ mkfifo _fifo
执行您的命令,将其输出流式传输到 FIFO
$ cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 > _fifo &
Run Code Online (Sandbox Code Playgroud)
或(消除无用的 cat)
$ tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 32 > _fifo &
Run Code Online (Sandbox Code Playgroud)从 FIFO 中获取行并将它们替换为目标文件的行
$ awk '{getline $2 < "_fifo"} 1' FS=, OFS=, file
Run Code Online (Sandbox Code Playgroud)删除先进先出
rm _fifo
Run Code Online (Sandbox Code Playgroud)测试:
$ mkfifo _fifo
$ tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 32 > _fifo &
[1] 5815
$ awk '{getline $2 < "_fifo"} 1' FS=, OFS=, file
SveUJW24ibppfePgYeYHz7fC0,hpqBxCOYIj7eQ9MgbPNG69SY3X3iAJ7A,yL6mCP0Do28k4EoTZUfKfqNYiIhGxxkA
xyRG8Da6kY35xeIT492Lul7xu,ACU1hyR8zGRfDMeUk4a6TFVcQvUAtZog,ne6RIM2TeMQAax1GgzL7FeDrnQyHPH1i
sxTf13KlAnjtXodJouQ9V6m5b,dkeKUnMYZepGcGMgdQc9IORa77Vtwr7w,GUnApYwwDCZxWGZtzKzTU6sJRgHlUUfQ
7cjW5DZlXw1LYzVugbVyqfxRX,UMjkPZAB3ElpOnXWnsQe9w1v0h6HMLPs,XttE1In9eZQ8puJVUriuNvx2AJAxviGf
XiLE8r9AMqy5YZQ9BbIS6m559,iz5tavnYqajwTokPCM4HJIsZlIloLcVy,DssiszVBa05pbVDSOXNRaFXRxw0eZKHf
Sygrl5287BViOn0uQ9uCYipB1,RHPFMgKoIGojvM6aTwb43lH4BAr8Jh5Y,sD2O46sbh1yVIluoyn6Zm2OKXYe05vV9
Qi6DxJ96M0hxNe4cgux3iJ1aS,fqTsEPr3PIPqIWPrb2uIl47QjXlSt3gL,wk2eF3f9xk5HowLzDIL3hCCNSmx8Uwi8
ZIX7qp5IIPekA0kzBdFR4IUQZ,uAFKvX5z2ik2i1AKh3wYp503xpNy8dxA,99ilfJWoJEBsKOfYI3buFfher07OCz6Y
rm _fifo
[1]+ Broken pipe cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 > _fifo
Run Code Online (Sandbox Code Playgroud)
随着GNU AWK,你可以做内部相当于用getline一个共同的过程:
$ gawk '{"tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 32" |& getline $2} 1' FS=, OFS=, file
SveUJW24ibppfePgYeYHz7fC0,hKOYDf6lgEtVwzJvCl34eYu22m5bZ11e,yL6mCP0Do28k4EoTZUfKfqNYiIhGxxkA
xyRG8Da6kY35xeIT492Lul7xu,bV9m4OgbTzDTJQanhS3BTmxr5gUcouDy,ne6RIM2TeMQAax1GgzL7FeDrnQyHPH1i
sxTf13KlAnjtXodJouQ9V6m5b,r9850TtXPJsLLNMupiwSPsqx7ovtb5ph,GUnApYwwDCZxWGZtzKzTU6sJRgHlUUfQ
7cjW5DZlXw1LYzVugbVyqfxRX,aRRVAecWxeTtt3WX36MIoFlMCvDcFb3a,XttE1In9eZQ8puJVUriuNvx2AJAxviGf
XiLE8r9AMqy5YZQ9BbIS6m559,BeCoCV4kMb8FUt6Y3RFxolI2CKqzbeuO,DssiszVBa05pbVDSOXNRaFXRxw0eZKHf
Sygrl5287BViOn0uQ9uCYipB1,WZ0hSxurp22dCdhV12Gjcms6rdx8hjM2,sD2O46sbh1yVIluoyn6Zm2OKXYe05vV9
Qi6DxJ96M0hxNe4cgux3iJ1aS,ujxdLQZo1vkCZnkUej6pLjZxVmN7XiTE,wk2eF3f9xk5HowLzDIL3hCCNSmx8Uwi8
ZIX7qp5IIPekA0kzBdFR4IUQZ,qxp3dwltN5Mxfece27Zvq2NqbjPlF358,99ilfJWoJEBsKOfYI3buFfher07OCz6Y
Run Code Online (Sandbox Code Playgroud)