Bash script for creating text in a file using arguments - bash

Imagine that you have to create many lines in file all with the same text except for one variable:
foo text $variable bar text
foo text $variable bar text
foo text $variable bar text
...
I was wondering if this could be made using a bash script passing it the variable as an argument:
./my_script '1'
./my_script '2'
./my_script '3'
Which would generate this:
foo text 1 bar text
foo text 2 bar text
foo text 3 bar text
Any suggestions or examples on how to do this?

See also http://tldp.org/LDP/abs/html/internalvariables.html#POSPARAMREF:
#!/bin/bash
echo "foo text ${1} bar text"

It's too trivial a task to write a script for.
Here are a couple of possible solutions:
for (( variable=1; variable<10; ++variable )); do
echo foo text $variable bar text
done
or...
for name in Dave Susan Peter Paul; do
echo "Did you know that $name is coming to my party?"
done

This might work for you:
printf "foo text %d bar text\n" {1..10}
foo text 1 bar text
foo text 2 bar text
foo text 3 bar text
foo text 4 bar text
foo text 5 bar text
foo text 6 bar text
foo text 7 bar text
foo text 8 bar text
foo text 9 bar text
foo text 10 bar text
or this:
printf "foo text %s bar text\n" foo bar baz
foo text foo bar text
foo text bar bar text
foo text baz bar text

Assuming you're stuck with that crappy template file:
perl -pe 'BEGIN {$count=0} s/\$variable/ ++$count /ge' file

This will depend on how you are getting "foo text" and "bar text". If it is set statically:
var="foo text $1 bar text"
echo "$var"
Or if it is in separate variables you can concatenate them:
foo="foo text"
bar="bar text"
output="$foo $1 $bar"
echo "$output"

Related

How to use :put to append a variable at the end of the current line with vim

I have the following command, which I need to insert in a bash script:
vim file.txt -c ':let var=$foo' -c ':execute "normal! gg/string\<cr>V"' -c ":normal! d" -c ':execute "normal inewstring\<Esc>"' -c ':put =var'
What it does (or what I want it to do) is to use the variable foo, which is defined on the script, search for the first appearance of string select the whole line and delete it, then insert newstring and append the value of foo just after this new string. However, my code puts the value always in the next line, no matter if I change the x value in :[x]put.
As a novice in vim I'm not sure even if this way to achieve my goal is efficient, so any suggestion is welcome. Thanks in advance.
Let's say that we have this input file:
$ cat file.txt
blah
string foo
string foo
blah
What I'm expecting to obtain (defining $foo="hello") is:
$ cat file.txt
blah
newstringhello
string foo
blah
I am a big vim fan, but if I were you, I won't do it with vim.
Since you didn't post the example input the desired output, I can only guess what do you want from your description.
Given that we have:
kent$ cat f
blah
string foo bar
string foo bar
blah
And var="hello", the next sed one-liner changes the input file into:
kent$ sed "0,/string/{/string/s/.*/newString/};$ a \\$var" f
blah
newString
string foo bar
blah
hello
However I don't know if it is exactly what you wanted.
update
kent$ sed "0,/string/{/string/s/.*/newString$var/}" f
blah
newStringhello
string foo bar
blah

Keep only nth line if keyword present

Assume a text file that contains lines starting with foo and bar, respectively. Assume further that I would like to print only every fourth line of the ones starting with bar; the lines starting with foo should always be printed.
foo bar qux
# Deliberate empty line
bar baz 1
bar baz 2
bar baz 3
bar baz 4
bar baz 5
bar baz 6
bar baz 7
bar baz 8
# A miscellaneous code comment
The following code prints every fourth line irrespective of the first word and is thus not what I am looking for.
awk '/^bar/ NR == 1 || NR % 4 == 0' infile
What would the correct code be (preferentially with awk)?
EDIT:
Thanks to fedorqui for his excellent suggestion. Considering the potential appearance of empty lines and comments in the input file, I am using the following code:
user$ awk '!/^bar/ || (/^bar/ && !(++c%4))' file
foo bar qux
# Deliberate empty line
bar baz 4
bar baz 8
# A miscellaneous code comment
Just use a counter:
awk '/^foo/ || (/^bar/ && !(++c%4))' file
This prints lines that accomplish either of these:
start with "foo"
start with "bar" and this happens for the 4th time, 8th... That is, every four times a line starts with "bar".
See it in action:
$ cat a
foo1
bar1
bar2
bar3
foo2
foo3
bar4
bar5
bar6
bar7
bar8
bar9
$ awk '/^foo/ || (/^bar/ && !(++c%4))' a
foo1
foo2
foo3
bar4
bar8
This should do the trick:
awk '/^bar/ && NR % 4 == 0 || /^foo/' infile

Display Unique Shell Columns

Given we have two formatted strings that are unrelated to each other.
#test.rb
string_1 = "Title\nfoo bar\nbaz\nfoo bar baz boo"
string_2 = "Unrelated Title\ndog cat farm\nspace moon"
How can I use ruby or call shell commands to have each of these string display as columns in terminal? The key is that the data of each string are not building a correlated row, ie this is not a table, rather 2 lists side by side.
Title Unrelated Title
foo bar dog cat farm
baz space moon
foo bar baz boo
You can try using paste and column command together. Note that this is a shell command so spaces between the assignment operator should be corrected.
$ string_1="Title\nfoo bar\nbaz\nfoo bar baz boo"
$ string_2="Unrelated Title\ndog cat farm\nspace moon"
$ paste -d '|' <(echo -e "$string_1") <(echo -e "$string_2") | column -s'|' -t
Title Unrelated Title
foo bar dog cat farm
baz space moon
foo bar baz boo
We paste the lines with | as delimiter and tell column command to use | as a reference to form columns.
In Ruby, you could do it this way:
#!/usr/bin/env ruby
string_1 = "Title\nfoo bar\nbaz\nfoo bar baz boo"
string_2 = "Unrelated Title\ndog cat farm\nspace moon"
a1 = string_1.split("\n")
a2 = string_2.split("\n")
a1.zip(a2).each { |pair| puts "%-20s%s" % [pair.first, pair.last] }
# or
# a1.zip(a2).each { |left, right| puts "%-20s%s" % [left, right] }
This produces:
Title Unrelated Title
foo bar dog cat farm
baz space moon
foo bar baz boo
Hi , If you Use temp files
string_1 = "Title\nfoo bar\nbaz\nfoo bar baz boo"
string_2 = "Unrelated Title\ndog cat farm\nspace moon"
echo -e $string_1 >a.txt
echo -e $string_2 >b.txt
paste a.txt b.txt
I hope it will help.

Redmine plugin that replaces words via regular expression?

I'm very new to Redmine/Ruby trying to achieve a simple plugin that takes the current wiki page content and matches/replaces everytime a word occurs via regular expression. How can I do this?
Thanks!
Dennis
The word replacement can de done by using gsub() with \b to match a word boundary:
irb(main):001:0> 'foo bar baz foo bar'.gsub /\bfoo\b/, 'replaced'
=> "replaced bar baz replaced bar"
Here is a more complete solution with a dictionary of words to replace:
repl = {'foo'=>'apple', 'baz'=>'banana'}
s = 'foo bar baz foo bar'
for from, to in repl:
s = s.gsub /\b#{from}\b/, to
end
Result: apple bar banana apple bar

How do I write one-liner script that inserts the contents of one file to another file?

Say I have file A, in middle of which have a tag string "#INSERT_HERE#". I want to put the whole content of file B to that position of file A. I tried using pipe to concatenate those contents, but I wonder if there is more advanced one-line script to handle it.
$ cat file
one
two
#INSERT_HERE#
three
four
$ cat file_to_insert
foo bar
bar foo
$ awk '/#INSERT_HERE#/{while((getline line<"file_to_insert")>0){ print line };next }1 ' file
one
two
foo bar
bar foo
three
four
cat file | while read line; do if [ "$line" = "#INSERT_HERE#" ]; then cat file_to_insert; else echo $line; fi; done
Use sed's r command:
$ cat foo
one
two
#INSERT_HERE#
three
four
$ cat bar
foo bar
bar foo
$ sed '/#INSERT_HERE#/{ r bar
> d
> }' foo
one
two
foo bar
bar foo
three
four

Resources