首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash文本文件编辑/修改

Bash文本文件编辑/修改
EN

Stack Overflow用户
提问于 2017-11-10 01:15:30
回答 2查看 139关注 0票数 0

我有一个文本文件,我正在试图修改。的形式有行的输入文件。

代码语言:javascript
复制
(y+1/4,-x+1/2,z+3/4)

并试图把它改成

代码语言:javascript
复制
   0     1     0    -1     0     0     0     0     1    1 / 4    1 / 2    3 / 4

我现在可以讲到这一点

代码语言:javascript
复制
   0     1     0 1/4    -1     0     0 1/2     0     0     1 3/4

使用

代码语言:javascript
复制
#!bin/bash
filename="227.dat"
sed -i 's/(/  /g' $filename
sed -i 's/)//g' $filename
sed -i 's/,/    /g' $filename
sed -i 's/-x/-1     0     0/g' $filename
sed -i 's/x/ 1     0     0/g' $filename
sed -i 's/-y/ 0    -1     0/g' $filename
sed -i 's/y/ 0     1     0/g' $filename
sed -i 's/-z/ 0     0    -1/g' $filename
sed -i 's/z/ 0     0     1/g' $filename
sed -i '/+/! s/$/    0 \/ 1    0 \/ 1    0 \/ 1/' $filename

while ((i++)); read -r line; do
  if [[ $line == *[+]* ]]
    then
      sed -i 's/+/ /g' $filename
      echo $i
  fi
done < "$filename"

echo $i的原因是看到它正确地给出了行号,我想也许我可以将它用于这些特定行上的命令。我正在进行这种转换,因为我们在创建晶体结构时所用的代码需要在末尾使用分数的向量表示法,而不是x、y、z表示法。我已经知道这不是“最漂亮”或最简单的解决方案,但我对所有这些都非常陌生,这也是迄今为止我能够拼凑起来的东西。有什么建议吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-10 01:48:05

代码语言:javascript
复制
#!/usr/bin/env bash

filename="227.dat"

re='[(]y[+]([[:digit:]/]+),-x[+]([[:digit:]/]+),z[+]([[:digit:]/]+)[)]';
while IFS= read -r line; do
    if [[ $line =~ $re ]]; then
        printf '\t%s' \
            0 1 0 \
           -1 0 0 \
            0 0 1 \
            "${BASH_REMATCH[1]}" \
            "${BASH_REMATCH[2]}" \
            "${BASH_REMATCH[3]}";
        printf '\n';
    else
        echo "ERROR: $line does not match $re" 1>&2;
    fi;
done <"$filename"

您的输入...given返回:

代码语言:javascript
复制
   0       1       0       -1      0       0       0       0       1       1/4     1/2     3/4

据我所知,...which是正确的。

一种更为复杂的方法,即进行毫无根据的推断(考虑到问题本身缺乏细节和范例),可能如下所示:

代码语言:javascript
复制
#!/usr/bin/env bash
while IFS='(),' read -a pieces; do
  declare -A vars=( [x]=1 [y]=1 [z]=1 [x_sigil]='' [y_sigil]='' [z_sigil]='' )
  for piece in "${pieces[@]}"; do
    #                1   2      3   4
    if [[ $piece =~ (-?)([xyz])([+]([[:digit:]/]+))? ]]; then
      if [[ ${BASH_REMATCH[4]} ]]; then                 # only if there *are* digits
        vars[${BASH_REMATCH[2]}]=${BASH_REMATCH[4]}     # ...then store them.
      fi
      vars[${BASH_REMATCH[2]}_sigil]=${BASH_REMATCH[1]} # store - if applicable
    fi
  done
  printf '\t%s' \
    "0"                 "${vars[x_sigil]}1" 0 \
    "${vars[y_sigil]}1" 0                   0 \
    0                   0                   "${vars[z_sigil]}1" \
    "${vars[y]}"        "${vars[x]}"        "${vars[z]}"
  printf '\n'
done

考虑到在对此答复的评论中提供的示例输入,输出如下:

代码语言:javascript
复制
0   1   0   1   0   0   0   0   1   1   1   1
0   1   0   1   0   0   0   0   1   1   1   1
0   1   0   1   0   0   0   0   1   1   1   1
0   1   0   1   0   0   0   0   -1  3/4 1/4 1/2
0   1   0   -1  0   0   0   0   1   1/2 3/4 1/4
0   -1  0   1   0   0   0   0   1   1/4 1/2 3/4
0   -1  0   -1  0   0   0   0   -1  1   1   1
0   -1  0   -1  0   0   0   0   -1  1   1   1
0   -1  0   -1  0   0   0   0   -1  1   1   1
0   -1  0   -1  0   0   0   0   1   1/4 3/4 1/2
0   -1  0   1   0   0   0   0   -1  1/2 1/4 3/4
0   1   0   -1  0   0   0   0   -1  3/4 1/2 1/4
0   -1  0   -1  0   0   0   0   1   1/4 3/4 1/2
0   -1  0   -1  0   0   0   0   1   1/4 3/4 1/2
0   -1  0   -1  0   0   0   0   1   1/4 3/4 1/2
0   -1  0   -1  0   0   0   0   -1  1   1   1
0   -1  0   1   0   0   0   0   1   1/4 1/2 3/4
0   1   0   -1  0   0   0   0   1   1/2 3/4 1/4
0   1   0   1   0   0   0   0   -1  3/4 1/4 1/2
0   1   0   1   0   0   0   0   -1  3/4 1/4 1/2
0   1   0   1   0   0   0   0   -1  3/4 1/4 1/2
0   1   0   1   0   0   0   0   1   1   1   1
0   1   0   -1  0   0   0   0   -1  3/4 1/2 1/4
0   -1  0   1   0   0   0   0   -1  1/2 1/4 3/4
0   -1  0   1   0   0   0   0   -1  1/2 1/4 3/4
0   -1  0   1   0   0   0   0   -1  1/2 1/4 3/4
0   -1  0   1   0   0   0   0   -1  1/2 1/4 3/4
0   -1  0   1   0   0   0   0   1   1/4 1/2 3/4
票数 0
EN

Stack Overflow用户

发布于 2017-11-10 02:42:25

下面是一种简化解析的方法。使用设置为所有可能的分隔符和字符的IFS将每一行读入数组:

代码语言:javascript
复制
while IFS=$'\(\)+,' read -ra line; do
    for i in 1 3 5; do
        case "${line[$i]}" in
            x) printf "%s\t%s\t%s\t" 1 0 0 ;;
            y) printf "%s\t%s\t%s\t" 0 1 0 ;;
            z) printf "%s\t%s\t%s\t" 0 0 1 ;;
            -x) printf "%s\t%s\t%s\t" -1 0 0 ;;
            -y) printf "%s\t%s\t%s\t" 0 -1 0 ;;
            -z) printf "%s\t%s\t%s\t" 0 0 -1 ;;
        esac
    done
    for i in 2 4 6; do
        printf "%s\t" "${line[$i]}"
    done
    echo
done < "$filename"
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47214248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档