How to create .txt and .csv files in Unix? - unix

I'm learning how to use the terminal and manage unix and I was wondering what is the way to make a .txt and a .csv to store some text information.

Navigate to the desired directory, e.g. cd Documents/SomeFolder
Run touch fileName.txt to create the file.
Run nano fileName.txt or vim fileName.txt to edit the file with nano or vim respectively.*
P.S. you can also skip the second step as once you exit and save the file it will automatically save it to the directory if it does not exist yet, so creating the file prior is not necessary.
*I prefer using nano as it is simple to use, once you are done editing simply press ctrl + x and it will prompt if you want to save before exiting. Vim is slightly more complex and you need to press i to enter insertion (editing) mode, then once you are done you need to press esc to exit insertion mode and then type :wq and enter to save.

echo "this is some text" > file.txt
echo "name,age,address" > file.csv
echo "Bob,37,123 Main St." >> file.csv
cat << EOF >> file.csv
Alice,34,23 Elm St.
Charlie,23,60 E. Birch Ave.
EOF

Related

Writing SoX Stats to File When Running via .bat

Amateur coder here. I have an old R script that runs SoX stats on files across multiple folders and writes the outputs to txt files. A peer requested to use it on their Windows machine and would like to be able to just click a .bat file to run it. I made one but it outputs SoX stats to the batch file window and the txt files the stats typically output to are blank. I've read it's because of how R handles stderr but I can't find a solution for my issue. I'm really only versed in R but have been teaching myself Python, so if there's an alternative language solution like that, I'm all ears.
My "sox-stats.R" Script
setwd("~/R/sox-stats/")
for(l in list.dirs(recursive=FALSE)){
setwd(paste0("~/R/sox-stats/", l))
print(paste0("Directory set to ", l))
dir.create("./stats/", showWarnings = FALSE)
directoryAll <- list.files()
statFolder <- list.files(pattern="stats")
for(file in setdiff(directoryAll, statFolder)){
firstSox <- paste("sox \"",file,"\" -n stats",sep="")
write(system(firstSox, intern = TRUE), paste("./stats/", file, "_stats.txt", sep=""))
print(paste0(file, " has been processed."))
}
}
My .bat File
#ECHO OFF
ECHO Hello, so you want to get some SoX Stats?
ECHO ------------------------------------------------
ECHO Press any key to start me up!
PAUSE >NUL
cd C:\Program Files\R\R-3.3.0\bin
rscript sox-stats.R
IF ERRORLEVEL 1 ECHO SoX Says: Something went wrong. Check messages
above for clues. Press any key to close SoX Stats.
IF NOT ERRORLEVEL 1 ECHO SoX Says: PROCESSING COMPLETE. Press any key to close this window
and open your "sox-stats" folder.
pause >nul
IF NOT ERRORLEVEL 1 %SystemRoot%\explorer.exe "C:\Users\user\Documents\R\sox-stats"
Thanks in advance!
One way to approach this would be to use Julia, which is available for Windows. The meat of the process would be something like:
run(pipeline(`soxi mytest.wav`,"soxi.out"))
This code uses backticks to signal a console command to Julia, sets up a pipe into a named file and runs the whole thing. You could examine the contents of directories as required with a readdir() into an array of filenames and place a filter on the array as required.

Using a vi-like editor to edit filenames in a directory

I often find myself editing the file names in a directory
I used to use vi a lot, and I always liked it
Has anyone adapted vi to facilitate editing filenames?
My thought is it would look like a regular file, but each line would be a file name, and various mv commands would run to change the filenames when saving
Is this crazy? Has anyone done it?
Thanks, Jim
You can invoke vim on a directory to start the explorer view which allows you to edit filenames.
Example for a directory named dir containing files file1 and file2: Running vim dir creates the interactive view as shown below.
" ============================================================================
" Netrw Directory Listing (netrw v153)
" /home/username/dir
" Sorted by name
" Sort sequence: [\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\
" Quick Help: <F1>:help -:go up dir D:delete R:rename s:sort-by x:special
" ==============================================================================
../
./
file1
file2
Using vim should be feasible for you because you asked for a vi-like editor.
check the vidir utility, here's the man page https://linux.die.net/man/1/vidir

unix script - problem in making a text file

I am writing a simple unix script as follows:
#!/bin/bash
mkdir tmp/temp1
cd tmp/temp1
echo "ab bc cj nn mm" > output.txt
grep 'ab' output.txt > newoutput.txt
I got following error message:
grep : No such file or directory found output.txt
but when I looked into the directory the text is created output.txt...but the type of the file was TXT....I am not sure what it is any help??
You probably have a stray '\r' (carriage return) on the line with the echo command. You're creating a file called "output.txt\r", and then trying to read a file called "output.txt" without the carriage return.
Fix the script so it uses Unix-style line endings (\n rather than \r\n). You can use the unix2dos command for this. (Note that unix2dos, unlike most filters, overwrites its input file.)

How to remove an entry from the history in ZSH

Let's say I ran a command using a zsh
echo "mysecret" > file
I can easily print the history including the entry numbers using the command fc -l:
1 echo "mysecret" >| file
But how can I easily delete an entry from the history?
I cannot find a corresponding paragraph in man zshbuiltins.
*BSD/Darwin (macOS):
LC_ALL=C sed -i '' '/porn/d' $HISTFILE
Linux (GNU sed):
LC_ALL=C sed -i '/porn/d' $HISTFILE
This will remove all lines matching "porn" from your $HISTFILE.
With setopt HIST_IGNORE_SPACE, you can prepend the above command with a space character to prevent it from being written to $HISTFILE.
As Tim pointed out in his comment below, the prefix LC_ALL=C prevents 'illegal byte sequence' failure.
I don't know if there is some elegant method for doing this, but in similar situations I have logged out (allowing zsh to empty its buffer and write my history to file), then logged in, and finally manually edited ~/.zsh_history, deleting the "dangerous" line.
If you use the HIST_IGNORE_SPACE option in zsh you can prepend commands with a space " " and they will not be remembered in the history file. If you have secret commands you commonly use you can do something along the lines of: alias hiddencommand=' hiddencommand'.
If you only want to make an occasional deletion, I think that it's easier to manually edit your .zsh_history.
In a zsh terminal:
Close the terminal session with the command to delete.
open a new session,
open ~/.zsh_history with a text editor (pico, Emacs, vim...),
delete the faulty lines,
close the editor, close the terminal session and open a new one,
enter history and the unwanted history item will be gone.
(Make sure the editor hasn't backed up the previous .zsh_history instance.)
(Solution based on https://til.hashrocket.com/posts/zn87awopb4-delete-a-command-from-zsh-history-)
This function will remove any one line you want from your Zsh history, no questions asked:
# Accepts one history line number as argument.
# Use `dc -1` to remove the last line.
dc () {
# Prevent the specified history line from being
# saved.
local HISTORY_IGNORE="${(b)$(fc -ln $1 $1)}"
# Write out the history to file, excluding lines that
# match `$HISTORY_IGNORE`.
fc -W
# Dispose of the current history and read the new
# history from file.
fc -p $HISTFILE $HISTSIZE $SAVEHIST
# TA-DA!
print "Deleted '$HISTORY_IGNORE' from history."
}
If you want to additionally prevent all dc commands from being written to history, add the following in your ~/.zshrc file:
zshaddhistory() {
[[ $1 != 'dc '* ]]
}
Update
I've now published a more comprehensive solution as a plugin: https://github.com/marlonrichert/zsh-hist
tldr:
vi $HISTFILE
more details:
run vi $HISTFILE
SHIFT + g — to go to the end
dd — to remove line
:wq — to save and exit
reload session or open a new tab to see changes
remove your line
In BASH [Not ZSH]:
1- in bash terminal type
hsitory # This will list all commands in history .bash_history file with line numbers
ex:
...
987 cd
988 ssh x#127.0.0.1
990 exit
991 cd
2- pick the CMD line number you want to delete
history -d 988
Note: if you want to delete for example last 3 CMDs, just pick the third line number from bottom ex: 988 and repeat the CMD history -d 988 3 times in sequence.
Source

Using the same file for stdin and stdout with redirection

I'm writing a application that acts like a filter: it reads input from a file (stdin), processes, and write output to another file (stdout). The input file is completely read before the application starts to write the output file.
Since I'm using stdin and stdout, I can run is like this:
$ ./myprog <file1.txt >file2.txt
It works fine, but if I try to use the same file as input and output (that is: read from a file, and write to the same file), like this:
$ ./myprog <file.txt >file.txt
it cleans file.txt before the program has the chance to read it.
Is there any way I can do something like this in a command line in Unix?
There's a sponge utility in moreutils package:
./myprog < file.txt | sponge file.txt
To quote the manual:
Sponge reads standard input and writes it out to the specified file. Unlike a shell redirect, sponge soaks up all its input before opening the output file. This allows constructing pipelines that read from and write to the same file.
The shell is what clobbers your output file, as it's preparing the output filehandles before executing your program. There's no way to make your program read the input before the shell clobbers the file in a single shell command line.
You need to use two commands, either moving or copying the file before reading it:
mv file.txt filecopy.txt
./myprog < filecopy.txt > file.txt
Or else outputting to a copy and then replacing the original:
./myprog < file.txt > filecopy.txt
mv filecopy.txt file.txt
If you can't do that, then you need to pass the filename to your program, which opens the file in read/write mode, and handles all the I/O internally.
./myprog file.txt # reads and writes according to its own rules
For a solution of a purely academic nature:
$ ( unlink file.txt && ./myprog >file.txt ) <file.txt
Possibly problematic side-effects are:
If ./myprog fails, you destroy your input. (Naturally...)
./myprog runs from a subshell (Use { ... ; } instead of ( ... ) to avoid.)
file.txt becomes a new file with a new inode and file permissions.
You need +w permission on the directory housing file.txt.

Resources