Я использую xbindkeys, который позволяет связывать сочетания клавиш с любой возможной командой - вы можете получить некоторые действительно сложные вещи через это.
Вы можете установить и запустить его так:
sudo apt-get install xbindkeys xbindkeys-config
xbindkeys-config
Инструкции здесь: http://www.nongnu.org/xbindkeys/xbindkeys.html
Я изначально думал, что мне придется создать дополнительный файл, но я мог бы просто закодировать исходный файл в Bash и использовать некоторое перенаправление, чтобы оно отображалось как файл.
Есть, вероятно, дюжина различные способы выполнения цикла, но здесь четыре:
mycommand <( seq 1000 | xargs -i -- cat input-data.txt )
mycommand <( for _ in {1..1000}; do cat input-data.txt; done )
mycommand <((for _ in {1..1000}; do echo input-data.txt; done) | xargs cat )
mycommand <(awk '{for(i=0; i<1000; i++)print}' input-data.txt) #*
Третий метод импровизирован из комментария maru ниже и строит большой список входных имен файлов для cat. xargs разделит это на столько аргументов, сколько позволит система. Это намного быстрее, чем n отдельных кошек.
Способ awk (вдохновленный ответом terdon), вероятно, наиболее оптимизирован, но он дублирует каждую строку за раз. Это может или не подходит для конкретного приложения, но оно быстро и эффективно.
Но это генерируется «на лету». Вывод Bash, вероятно, будет намного медленнее, чем что-то, что можно прочитать, поэтому вы должны создать новый файл для тестирования. К счастью, это очень простое расширение:
(for _ in {1..1000}; do echo input-data.txt; done) | xargs cat > input-duplicated.txt
mycommand input-duplicated.txt
Вот решение awk:
awk '{a[NR]=$0}END{for (i=0; i<1000; i++){for(k in a){print a[k]}}}' file
Это по существу так же быстро, как Perl @ Gnuc (я побежал и 1000 раз и получил среднее время):
$ for i in {1..1000}; do
(time awk '{a[NR]=$0}END{for (i=0;i<1000;i++){for(k in a){print a[k]}}}' file > a) 2>&1 |
grep -oP 'real.*?m\K[\d\.]+'; done | awk '{k+=$1}END{print k/1000}';
0.00426
$ for i in {1..1000}; do
(time perl -0777pe '$_=$_ x 1000' file > a ) 2>&1 |
grep -oP 'real.*?m\K[\d\.]+'; done | awk '{k+=$1}END{print k/1000}';
0.004076
Я бы просто использовал текстовый редактор.
vi input-data.txt
gg (move cursor to the beginning of the file)
yG (yank til the end of the file)
G (move the cursor to the last line of the file)
999p (paste the yanked text 999 times)
:wq (save the file and exit)
Если вам абсолютно необходимо сделать это через командную строку (для этого вам необходимо установить vim, поскольку vi doesn ' t имеет команду :normal), вы можете использовать:
vim -es -u NONE "+normal ggyGG999p" +wq input-data.txt
Здесь -es (или -e -s) делает vim бесшумным, поэтому он не должен захватывать ваше окно терминала, и -u NONE останавливает его от просмотра вашего vimrc, что должно заставить его работать немного быстрее, чем в противном случае (возможно, намного быстрее, если вы используете много плагинов vim).
Вот простой однострочный скрипт, никаких скриптов:
mycommand <(cat `yes input-data.txt | head -1000 | paste -s`)
При работе с совершенно другим сценарием я узнал, что с 29 миллионами строк текста, используя seek() и работая по данным, часто быстрее, чем по очереди. Такая же идея применяется в приведенном ниже скрипте: мы открываем файл и вместо того, чтобы зацикливаться на открытии и закрытии файла (что может привести к увеличению накладных расходов, даже если это не существенно), мы сохраняем файл открытым и возвращаемся к началу.
#!/usr/bin/env python3
from __future__ import print_function
import sys,os
def error_out(string):
sys.stderr.write(string+"\n")
sys.exit(1)
def read_bytewise(fp):
data = fp.read(1024)
print(data.decode(),end="",flush=True)
while data:
data = fp.read(1024)
print(data.decode(),end="",flush=True)
#fp.seek(0,1)
def main():
howmany = int(sys.argv[1]) + 1
if not os.path.isfile(sys.argv[2]):
error_out("Needs a valid file")
fp = open(sys.argv[2],'rb')
for i in range(1,howmany):
#print(i)
fp.seek(0)
read_bytewise(fp)
fp.close()
if __name__ == '__main__': main()
Сам скрипт довольно прост в использовании:
./repeat_text.py <INT> <TEXT.txt>
Для 3-строчного текстового файла и 1000 итераций все идет хорошо, около 0,1 секунды:
$ /usr/bin/time ./repeat_text.py 1000 input.txt > /dev/null
0.10user 0.00system 0:00.23elapsed 45%CPU (0avgtext+0avgdata 9172maxresident)k
0inputs+0outputs (0major+1033minor)pagefaults 0swaps
Сам скрипт не самый элегантный, возможно, он может быть сокращен, но выполняет эту работу. Конечно, я добавил несколько лишних бит здесь и там, например error_out(), что не обязательно - это просто небольшое удобное для пользователя прикосновение.
Мы можем решить это без дополнительного файла или специальных программ, чистого Bash (ну, cat - стандартная команда).
Основываясь на функции printf внутри bash, мы можем генерировать повторяющуюся строку) :
printf "test.file.txt %.0s\n" {1..1000}
Затем мы можем отправить такой список из 1000 имен файлов (повторить) и вызвать cat:
printf "test.file.txt %.0s" {1..1000} | xargs cat
И, наконец, мы можем дать вывод команде execute:
mycommand "$( printf "%.0sinput.txt\n" {1..1000} | xargs cat )"
Или, если команде необходимо получить вход в stdin:
mycommand < <( printf "%.0sinput.txt\n" {1..1000} | xargs cat )
Да, double & lt; необходим.
Я бы сгенерировал новый файл, используя Unix for loop:
content=$(cat Alex.pgn); for i in {1..900000}; do echo "$content" >> new_file; done
Мы можем решить это без дополнительного файла или специальных программ, чистого Bash (ну, cat - стандартная команда).
Основываясь на функции printf внутри bash, мы можем генерировать повторяющуюся строку) :
printf "test.file.txt %.0s\n" {1..1000}
Затем мы можем отправить такой список из 1000 имен файлов (повторить) и вызвать cat:
printf "test.file.txt %.0s" {1..1000} | xargs cat
И, наконец, мы можем дать вывод команде execute:
mycommand "$( printf "%.0sinput.txt\n" {1..1000} | xargs cat )"
Или, если команде необходимо получить вход в stdin:
mycommand < <( printf "%.0sinput.txt\n" {1..1000} | xargs cat )
Да, double & lt; необходим.
Мы можем решить это без дополнительного файла или специальных программ, чистого Bash (ну, cat - стандартная команда).
Основываясь на функции printf внутри bash, мы можем генерировать повторяющуюся строку) :
printf "test.file.txt %.0s\n" {1..1000}
Затем мы можем отправить такой список из 1000 имен файлов (повторить) и вызвать cat:
printf "test.file.txt %.0s" {1..1000} | xargs cat
И, наконец, мы можем дать вывод команде execute:
mycommand "$( printf "%.0sinput.txt\n" {1..1000} | xargs cat )"
Или, если команде необходимо получить вход в stdin:
mycommand < <( printf "%.0sinput.txt\n" {1..1000} | xargs cat )
Да, double & lt; необходим.
Мы можем решить это без дополнительного файла или специальных программ, чистого Bash (ну, cat - стандартная команда).
Основываясь на функции printf внутри bash, мы можем генерировать повторяющуюся строку) :
printf "test.file.txt %.0s\n" {1..1000}
Затем мы можем отправить такой список из 1000 имен файлов (повторить) и вызвать cat:
printf "test.file.txt %.0s" {1..1000} | xargs cat
И, наконец, мы можем дать вывод команде execute:
mycommand "$( printf "%.0sinput.txt\n" {1..1000} | xargs cat )"
Или, если команде необходимо получить вход в stdin:
mycommand < <( printf "%.0sinput.txt\n" {1..1000} | xargs cat )
Да, double & lt; необходим.
Мы можем решить это без дополнительного файла или специальных программ, чистого Bash (ну, cat - стандартная команда).
Основываясь на функции printf внутри bash, мы можем генерировать повторяющуюся строку) :
printf "test.file.txt %.0s\n" {1..1000}
Затем мы можем отправить такой список из 1000 имен файлов (повторить) и вызвать cat:
printf "test.file.txt %.0s" {1..1000} | xargs cat
И, наконец, мы можем дать вывод команде execute:
mycommand "$( printf "%.0sinput.txt\n" {1..1000} | xargs cat )"
Или, если команде необходимо получить вход в stdin:
mycommand < <( printf "%.0sinput.txt\n" {1..1000} | xargs cat )
Да, double & lt; необходим.
Мы можем решить это без дополнительного файла или специальных программ, чистого Bash (ну, cat - стандартная команда).
Основываясь на функции printf внутри bash, мы можем генерировать повторяющуюся строку) :
printf "test.file.txt %.0s\n" {1..1000}
Затем мы можем отправить такой список из 1000 имен файлов (повторить) и вызвать cat:
printf "test.file.txt %.0s" {1..1000} | xargs cat
И, наконец, мы можем дать вывод команде execute:
mycommand "$( printf "%.0sinput.txt\n" {1..1000} | xargs cat )"
Или, если команде необходимо получить вход в stdin:
mycommand < <( printf "%.0sinput.txt\n" {1..1000} | xargs cat )
Да, double & lt; необходим.