使用变量来更改Bash中的标志以切换命令。

huangapple go评论132阅读模式
英文:

Use variable to change flag to cut command in bash

问题

以下是翻译好的代码部分:

  1. file=~/Desktop/test.geno.file.txt
  2. if cat $file | awk '{exit !/\t/}'; then
  3. echo "Tab delimited" # tab file
  4. FILESEP=""
  5. else
  6. FILESEP="-d \ "
  7. echo "Space delimited with $FILESEP" # space file
  8. fi
  9. onlyfile=$(basename $file)
  10. POSFILE=${onlyfile%.txt}.pos.gz # Next command will generate it
  11. cat $file | cut $FILESEP -f 1 | perl -p -e 's/_([^_]+$)/\t$1/' | grep -v marker | gzip > ~/Desktop/$POSFILE # Keep position only chr \t pos

希望这对你有所帮助。如果你需要进一步的协助,请随时提问。

英文:

I have a file test.geno.file.txt which contains chromosome and alleles and some numbers in it (this one is SPACE separated, but I have another which is TAB separated):

  1. marker allele1 allele2 id1 id1 id2 id2
  2. chr11_96001606 C T 1.25893e-12 1 3.16228e-26 0.000999001
  3. chr1_46021459 G T 0.969347 0.0306534 1.22034e-21 0.996035

I'm using a script that checks if it is tab or space delimited and stores the result inside the FILESEPvariable:

  1. file=~/Desktop/test.geno.file.txt
  2. if cat $file | awk '{exit !/\t/}'; then
  3. echo "Tab delimited" # tab file
  4. FILESEP=""
  5. else
  6. FILESEP="-d \ "
  7. echo "Space delimited with $FILESEP" # space file
  8. fi
  9. onlyfile=$(basename $file)

Basically, I want to modify the original file to get the chromosome names and positions separated. I'm using the cut command, but I would like to make it easier to change the delimiter flag (using the if statement and variable above)

Like this:

  1. POSFILE=${onlyfile%.txt}.pos.gz # Next command will generate it
  2. cat $file | cut -d' ' -f 1 | perl -p -e 's/_([^_]+$)/\t$1/' | grep -v marker | gzip > ~/Desktop/$POSFILE # Keep position only chr \t pos

This is the output:

  1. gunzip -c ~/Desktop/$POSFILE
  2. chr11 96001606
  3. chr1 46021459

But changing the -d' ' with $FILESEP:

  1. cat $file | cut $FILESEP -f 1 | perl -p -e 's/_([^_]+$)/\t$1/' | grep -v marker | gzip > ~/Desktop/$POSFILE # Keep position only chr \t pos

But this last command doesn't work...

答案1

得分: 3

假设没有任何字段包含空格,我会用awk替换cut,其中默认分隔符是空格(空格、连续空格、制表符、连续制表符)。 这将消除整个if/then/else结构以确定要放入FILESEP中的内容。
换句话说...

用这个替换:

  1. if cat $file | awk '{exit !/\t/}'; then
  2. echo "Tab delimited" # tab file
  3. FILESEP=""
  4. else
  5. FILESEP="-d \ "
  6. echo "Space delimited with $FILESEP" # space file
  7. fi
  8. ....
  9. cat $file | cut $FILESEP -f 1 | perl ...

用这个:

  1. awk '{print $1}' "${file}" | perl ...
  2. # 或者如果使用zcat(根据楼主评论中的一个)
  3. zcat "${file}" | awk '{print $1}' | perl ...

注意: 我不用perl,但如果你不能在perl中模拟这个awk脚本的话,我会感到惊讶(也就是说,通过在perl脚本中添加一些额外的代码来消除awk调用)... ??

英文:

Assuming none of the fields contain spaces, I'd replace cut with awk where the default delimiter is white space (space, contiguous spaces, tab, contiguous tabs). This would do away with the whole if/then/else construct do determine what to put in FILESEP.
In other words ...

Replace this:

  1. if cat $file | awk '{exit !/\t/}'; then
  2. echo "Tab delimited" # tab file
  3. FILESEP=""
  4. else
  5. FILESEP="-d \ "
  6. echo "Space delimited with $FILESEP" # space file
  7. fi
  8. ....
  9. cat $file | cut $FILESEP -f 1 | perl ...

With this:

  1. awk '{print $1}' "${file}" | perl ...
  2. # or if using zcat (per one of OP's comments)
  3. zcat "${file}" | awk '{print $1}' | perl ...

NOTE: I don't work with perl but I'd be surprised if you couldn't emulate this awk script inside perl (ie, eliminate the awk call with some additional code in the perl script) ... ??

答案2

得分: 2

引用在扩展参数时至关重要。在扩展参数时不引用参数几乎总是一个错误,shellcheck会正确地抱怨这一点。

在这种情况下的解决方法是始终指定分隔符:

  1. if awk '{exit !/\t/}' "$file"; then
  2. FILESEP=$'\t' # 一个字面上的制表符。在终端中,通过按Ctrl-v Tab或Ctrl-v Ctrl-i来输入
  3. else
  4. FILESEP=' '
  5. fi
  6. cut -d "$FILESEP" -f1 yourfile
英文:

Quoting is crucial when expanding parameters. Not quoting a parameter when expanding is almost always an error and shellcheck will rightfully complain about it.

The solution in this case is to always specify the delimiter:

  1. if awk '{exit !/\t/}' "$file"; then
  2. FILESEP=' ' # a literal tab character. In terminal, enter by pressing Ctrl-v Tab, or Ctrl-v Ctrl-i
  3. else
  4. FILESEP=' '
  5. fi
  6. cut -d "$FILESEP" -f1 yourfile

huangapple
  • 本文由 发表于 2023年8月11日 02:25:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76878410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定