Как использовать read -ra inline?

Мне нужно запустить команду из python, поэтому я делаю:

os.system('IFS=".";for f in data/* ; do read -ra ADDR <<< "$f"; mv "$f" "data/${ADDR[-1]}"; done;')

, но он говорит:

sh: 1: Syntax error: redirection unexpected

Но если я запустил это в bash, это сработает fine:

IFS="." for f in data/* do read -ra ADDR <<< "$f" mv "$f" "data/${ADDR[-1]}" done;

Он работает нормально. Как я могу исправить это для работы в одной строке?

1
задан 4 January 2018 в 22:49

6 ответов

@steeldriver определил проблему. Вы можете решить это с помощью:

import subprocess
subprocess.run(['bash', '-c', '''
    IFS="."
    for f in data/*; do
        read -ra ADDR <<< "$f"
        [[ ${#ADDR[@]} -gt 0 ]] && mv "$f" "data/${ADDR[-1]}"
    done
'''])

, но в этот момент вам, вероятно, лучше всего делать все это в python, а не вызывать bash: что-то вроде

for f in os.scandir("data"):
    if f.is_file():
        addr = f.name.split(".")[-1]
        if f.name != addr:
            os.rename(f.path, "data/"+addr)
4
ответ дан 22 May 2018 в 15:45
  • 1
    Я согласен с этим методом чистого питона. – Thomas Ward♦ 4 January 2018 в 23:21
  • 2
    Но у меня огромное количество файлов. не мой подход к bash быстрее? – yukashima huksay 4 January 2018 в 23:32
  • 3
    Почему я должен использовать подпроцесс вместо os? – yukashima huksay 4 January 2018 в 23:34
  • 4
    os.system принимает только одну строку в качестве аргумента, поэтому вы должны указывать такие игры, как ответ toliveira. subprocess.run принимает список строк. Что касается производительности, вам придется сравнивать ее, но я был бы удивлен, если бы версия bash была бы быстрее. – glenn jackman 4 January 2018 в 23:42
  • 5
    @glennjackman ваш код подпроцесса дает мне ошибку – yukashima huksay 5 January 2018 в 19:39

@steeldriver определил проблему. Вы можете решить это с помощью:

import subprocess subprocess.run(['bash', '-c', ''' IFS="." for f in data/*; do read -ra ADDR <<< "$f" [[ ${#ADDR[@]} -gt 0 ]] && mv "$f" "data/${ADDR[-1]}" done '''])

, но в этот момент вам, вероятно, лучше всего делать все это в python, а не вызывать bash: что-то вроде

for f in os.scandir("data"): if f.is_file(): addr = f.name.split(".")[-1] if f.name != addr: os.rename(f.path, "data/"+addr)
4
ответ дан 17 July 2018 в 23:51

@steeldriver определил проблему. Вы можете решить это с помощью:

import subprocess subprocess.run(['bash', '-c', ''' IFS="." for f in data/*; do read -ra ADDR <<< "$f" [[ ${#ADDR[@]} -gt 0 ]] && mv "$f" "data/${ADDR[-1]}" done '''])

, но в этот момент вам, вероятно, лучше всего делать все это в python, а не вызывать bash: что-то вроде

for f in os.scandir("data"): if f.is_file(): addr = f.name.split(".")[-1] if f.name != addr: os.rename(f.path, "data/"+addr)
4
ответ дан 24 July 2018 в 17:07

После комментария @steeldriver и @glenn jackman ответы:

os.system('/bin/bash -c \'IFS=".";for f in data/* ; do read -ra ADDR <<< "$f";     mv "$f" "data/${ADDR[-1]}"; done; \' ')
1
ответ дан 22 May 2018 в 15:45
  • 1
    Если вы не уверены, что bash находится в / bin / bash, используйте только bash вместо / bin / bash. – toliveira 4 January 2018 в 23:36

После комментария @steeldriver и @glenn jackman ответы:

os.system('/bin/bash -c \'IFS=".";for f in data/* ; do read -ra ADDR <<< "$f"; mv "$f" "data/${ADDR[-1]}"; done; \' ')
1
ответ дан 17 July 2018 в 23:51

После комментария @steeldriver и @glenn jackman ответы:

os.system('/bin/bash -c \'IFS=".";for f in data/* ; do read -ra ADDR <<< "$f"; mv "$f" "data/${ADDR[-1]}"; done; \' ')
1
ответ дан 24 July 2018 в 17:07
  • 1
    Если вы не уверены, что bash находится в / bin / bash, используйте только bash вместо / bin / bash. – toliveira 4 January 2018 в 23:36

Другие вопросы по тегам:

Похожие вопросы: