What command makes a new file in terminal? - terminal

If mkdir creates a new directory, what creates a new file? for example "something.text".
I tried couple of commands mkdir (FileName) -- works fine. But I didn't know how to create a new file inside a directory. I know that I can always go to my project folder then create my new file but I want to know how to do that using terminal to increase productivity.

On Linux there are mutiple options
The typical used one is touch
touch bar.txt
However you may also use echo if you want to create and write to the file right away
The following command tells to create bar.txt and put foo inside of it
echo foo > bar.txt
You may also use >> which appends to an existing file
The following command puts bar at the end of bar.txt, in a other words, bar will display after foo inside bar.txt
echo bar >> bar.txt

You can either use touch:
$ touch something.txt
or > operator to redirect nothing to a file and effectively creating it:
$ > something.txt
or
$ : > something.txt
Note that last 2 commands will truncate file contents if file already exists.

If you mean on Linux so the command is touch.

Related

Process an external script using Makefile variables

I'm trying to include an external preprocess script to my current Makefile flow.
The external script location is /home/preprocessscript.sh, and content is:
cd ${path}; rm -rf *
Makefile content is:
path=/home/rubbish
clean:
cat ${preprocessscript} >> clean.sh
I execute the command by:
make clean preprocessscript=/home/preprocessscript.sh
./clean.sh
The problem is clean.sh doesn't get path. Its content will be:
cd ; rm -rf *
How do I pass the make variable to preprocessscript?
The problem is clean.sh doesn't get path. Its content will be:
cd ; rm -rf *
I'm sorry about the contents of your home directory.
Anyway, no. The cat command will output the contents of the original file verbatim. It will not interpret them in any way, and in particular, it will not attempt to expand shell-style variable references within.
Supposing that you have faithfully represented your situation, what you actually see is that when you run the resulting clean.sh as a script, the ${path} within expands to nothing. This is not particularly surprising, because nowhere in what you've presented is an environment variable named path defined. You have defined a make variable of that name, but that's not the same thing, and it anyway would not have an effect persisting past the end of the make run to when the generated script is executed.
I guess the idea is that you want to use the original file as a template to generate content for clean.sh. There are lots of ways to do that sort of thing, but the one closest to your current attempt would probably be to output (shell) variable assignments into the generated script, like so:
path = /home/rubbish
clean:
echo "path='$(path)'" >> clean.sh
cat ${preprocessscript} >> clean.sh
The generated script lines would then be
path='/home/rubbish'
cd ${path}; rm -rf *
Note also that there appear to be several other issues with the general approach presented in the question, but I am focusing my comments on the specific question asked.
You can export a make variable to the shell before running your command and use envsubst to expand the variables in the file as so:
path=/home/rubbish
clean:
export path=${path}; envsubst < ${preprocessscript} >> clean.sh
notice that the export has to be on the same recipe line as the command. You can also pipe the output of a command to envsubst: cat ${preprocessscript} | envsubst >> clean.sh. This might be useful if you're trying to do something more complicated like only print a few lines, etc.

How could I make a directory and navigate to the directory by only typing the name of the directory once using bash? [duplicate]

I'm searching for just one command — nothing with && or | — that creates a directory and then immediately changes your current directory to the newly-created directory. (This is a question someone got for his exams of "linux-usage", he made a new command that did that, but that didn't give him the points.) This is on a debian server if that matters.
I believe you are looking for this:
mkdir project1 && cd "$_"
define a bash function for that purpose in your $HOME/.bashrc e.g.
function mkdcd () {
mkdir "$1" && cd "$1"
}
then type mkdcd foodir in your interactive shell
So stricto sensu, what you want to achieve is impossible without a shell function containing some && (or at least a ; ) ... In other words, the purpose of the exercise was to make you understand why functions (or aliases) are useful in a shell....
PS it should be a function, not a script (if it was a script, the cd would affect only the [sub-] shell running the script, not the interactive parent shell); it is impossible to make a single command or executable (not a shell function) which would change the directory of the invoking interactive parent shell (because each process has its own current directory, and you can only change the current directory of your own process, not of the invoking shell process).
PPS. In Posix shells you should remove the functionkeyword, and have the first line be mkdcd() {
For oh-my-zsh users: take 'directory_name'
Reference: Official oh-my-zsh github wiki
Putting the following into your .bash_profile (or equivalent) will give you a mkcd command that'll do what you need:
# mkdir, cd into it
mkcd () {
mkdir -p "$*"
cd "$*"
}
This article explains it in more detail
I don't think this is possible but to all people wondering what is the easiest way to do that (that I know of) which doesn't require you to create your own script is:
mkdir /myNewDir/
cd !$
This way you don't need to write the name of the new directory twice.
!$ retrieves the last ($) argument of the last command (!).
(There are more useful shortcuts like that, like !!, !* or !startOfACommandInHistory. Search on the net for more information)
Sadly mkdir /myNewDir/ && cd !$ doesn't work: it retrieves the last of argument of the previous command, not the last one of the mkdir command.
Maybe I'm not fully understanding the question, but
>mkdir temp ; cd temp
makes the temp directory and then changes into that directory.
mkdir temp ; cd temp ; mv ../temp ../myname
You can alias like this:
alias mkcd 'mkdir temp ; cd temp ; mv ../temp ../'
You did not say if you want to name the directory yourself.
cd `mktemp -d`
Will create a temp directory and change into it.
Maybe you can use some shell script.
First line in shell script will create the directory and second line will change to created directory.

How do I call rename successfully from a bash script on Ubuntu?

I have a bash script #!/usr/bin/env bash that is called part of a make process. This script creates a directory with the files pertinent to a realise and then tars them up. I would like to take a copy of the directory and rename some of the files to replace the version identifier with the word "latest". This will make it simple to script the acquisition of the latest file from a web-server. When I run my script, the call to rename seems to do nothing, why is that?
#!/usr/bin/env bash
DATE_NOW="$(date +'%Y%m%d')"
product_id_base="$1"
firmware_dir="${product_id_base}-full-${DATE_NOW}"
# ...rest of file ommitted to protest the innocent
# It creates and fills the ${firmware_dir} with some files that end in
# -$DATE_NOW.<extention> and I would like to rename the copies of them so that they end in
# -latest.<extention>
cp -a "./${firmware_dir}" "./${product_id_base}-full-latest"
# see what there is in pwd
cd "./${product_id_base}-full-latest"
list_output=`ls`
echo $list_output
# Things go OK until this point.
replacment="'s/${DATE_NOW}/latest/'"
rename_path=$(which rename)
echo $replacment
perl $rename_path -v $replacment *
echo $cmd
pwd
$cmd
echo "'s/-${DATE_NOW}/-latest/g'" "${product_id_base}-*"
echo $a
# check what has happened
list_output=`ls`
echo $list_output
I call the above with ./rename.sh product-id and get the expected output from ls that indicates the present working directory is the one full of files that I want renamed.
$ ./rename.sh product-id ET-PIC-v1.1.dat ET-PIC-v1.1.hex
product-id-20160321.bin product-id-20160321.dat
product-id-20160321.elf product-id-20160321.gz 's/20160321/latest/'
/home/thomasthorne/work/product-id/build/product-id-full-latest
's/-20160321/-latest/g' product-id-*
ET-PIC-v1.1.dat ET-PIC-v1.1.hex product-id-20160321.bin
product-id-20160321.dat product-id-20160321.elf product-id-20160321.gz
What I hopped to see was some renamed files. When I directly call the rename function from a terminal emulator I see the rename occur.
~/work/product-id/build/product-id-full-latest$ rename -vn
's/-20160321/-latest/g' * product-id-20160321.bin renamed as
product-id-latest.bin product-id-20160321.dat renamed as
product-id-latest.dat product-id-20160321.elf renamed as
product-id-latest.elf ...
I have tried a few variations on escaping the strings, using ` or $(), removing all the substitutions from the command line. So far nothing has worked so I must be missing something fundamental.
I have read that #!/usr/bin/env bash behaves much like #!/bin/bash so I don't think that is at play. I know that Ubuntu and Debian have different versions of the rename script to some other distributions and I am running on Ubuntu. That lead me to try calling perl /usr/bin/rename ... instead of just rename but that seems to have made no perceivable difference.
This string:
replacment="'s/${DATE_NOW}/latest/'"
will be kept exactly the same because you put it between single quotes.
Have you tried with:
replacment="s/${DATE_NOW}/latest/"
This one worked on my Ubuntu, without perl:
$ ./test_script
filename_20160321 renamed as filename_latest
filename2_20160321 renamed as filename2_latest
filename3_20160321 renamed as filename3_latest
test_script content being:
#!/bin/bash
DATE_NOW="$(date +'%Y%m%d')"
replacment="s/${DATE_NOW}/latest/"
rename -v $replacment *

How to write to a text file upon creation?

I'm self-learning command line code and can't seem to find an answer.
I'm using the standard MacOS Terminal application to create directories/files for practice.
my question is, can I use a code to include what would get written to the file as I create it?
I've tried:
touch one/texttest.txt echo "Hello"
But this only creates 3 files, one called hello, one called echo, and a third called texttest.txt within the "one" folder
I've also tried these and got the same results:
touch echo "Hello" ~/one/texttest.txt
echo Hello ~/one/texttest.txt
touch one/texttest.txt Hello
I can't seem to find any solutions for the standard terminal app with 0 plugins, is this even possible?
This should work:
echo "Hello" > one/texttest.txt
touch one/texttest.txt echo "Hello"
That is the touch command with three arguments: one/texttest.txt, echo, and Hello (the shell removes the quotes).
touch echo "Hello" ~/one/texttest.txt
touch one/texttest.txt Hello
These are the same as the first one (different arguments but same concept).
echo Hello ~/one/texttest.txt
This is the echo command with two arguments: Hello, and ~/one/texttest.txt (only the ~ will have been expanded to your home directory by the time echo sees it).
touch only creates files (and updates timestamps) it doesn't write content.
You could have a touch command that takes content also but I don't know of one.
Luckily you don't need one because the shell can do this for you.
You use echo Hello to run echo and have it spit out Hello and you tell the shell to "redirect" the text to a file instead of the screen.
echo Hello > texttest.txt
It is worth pointing out that redirection creates the file whether you write anything to it or not (and in fact whether the command works or even exists or even if a command is given).
$ ls /tmp/texttest.txt
ls: /tmp/texttest.txt: No such file or directory
$ flekjfe Hello > /tmp/texttest.txt
$ ls /tmp/texttest.txt
/tmp/texttest.txt
So you can use > file all by itself to create a new empty file for example.
You can use output redirection command_output > file
For more details : http://tldp.org/LDP/abs/html/io-redirection.html

Batch renaming files in OSX terminal

I'm trying to rename files e.g. screen-0001.tif to 0001.tif using the approach in this SO question:
for file in *.tif
do
echo mv "$file" "${screen-/file}"
done
fails to change anything. Grateful for an idea where I'm going wrong.
The easier, IMHO, way to do this is using Perl's rename script. Here I am using it with --dry-run so it just tells you what it would do, rather than actually doing anything. You would just remove --dry-run if/when you are happy with the command:
rename --dry-run 's/screen-//' *tif
'screen-001.tif' would be renamed to '001.tif'
'screen-002.tif' would be renamed to '002.tif'
'screen-003.tif' would be renamed to '003.tif'
'screen-004.tif' would be renamed to '004.tif'
It has the added benefit that it will not overwrite any files that happen to come out to the same name. So, if you had files:
screen-001.tif
0screen-01.tif
And you did this, you would get:
rename 's/screen-//' *tif
'screen-001.tif' not renamed: '001.tif' already exists
rename is easily installed using Homebrew, using:
brew install rename
Two things:
You're echoing the commands and not actually executing them. I will do this when I do massive renames just to make sure that the command works correctly. I can redirect the output to a file, and then use that file as a shell script.
The substitution is wrong. There are two ways:
Left most filter ${file#screen-}.
Substitution: ${file/screen/}
The name of the environment variable always goes first. Then the pattern type, then the pattern
Here's how I would do this:
$ for file in *.tif
> do
> echo "mv '$file' '${file#screen-}'"
> done | tee mymove.sh # Build a shell script
$ vi mymove.sh # Examine the shell script and make sure everything is correct
$ bash mymove.sh # If all is good, execute the shell script.

Resources